mirror of
https://github.com/lWolvesl/claw-code.git
synced 2026-04-02 07:41:52 +08:00
wip: hook progress UI + documentation
This commit is contained in:
@@ -5,7 +5,7 @@ use crate::compact::{
|
||||
compact_session, estimate_session_tokens, CompactionConfig, CompactionResult,
|
||||
};
|
||||
use crate::config::RuntimeFeatureConfig;
|
||||
use crate::hooks::{HookAbortSignal, HookRunResult, HookRunner};
|
||||
use crate::hooks::{HookAbortSignal, HookProgressReporter, HookRunResult, HookRunner};
|
||||
use crate::permissions::{
|
||||
PermissionContext, PermissionOutcome, PermissionPolicy, PermissionPrompter,
|
||||
};
|
||||
@@ -100,6 +100,7 @@ pub struct ConversationRuntime<C, T> {
|
||||
usage_tracker: UsageTracker,
|
||||
hook_runner: HookRunner,
|
||||
hook_abort_signal: HookAbortSignal,
|
||||
hook_progress_reporter: Option<Box<dyn HookProgressReporter>>,
|
||||
}
|
||||
|
||||
impl<C, T> ConversationRuntime<C, T>
|
||||
@@ -171,6 +172,77 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
fn run_pre_tool_use_hook(&mut self, tool_name: &str, input: &str) -> HookRunResult {
|
||||
if let Some(reporter) = self.hook_progress_reporter.as_mut() {
|
||||
self.hook_runner.run_pre_tool_use_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
Some(&self.hook_abort_signal),
|
||||
Some(reporter.as_mut()),
|
||||
)
|
||||
} else {
|
||||
self.hook_runner.run_pre_tool_use_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
Some(&self.hook_abort_signal),
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn run_post_tool_use_hook(
|
||||
&mut self,
|
||||
tool_name: &str,
|
||||
input: &str,
|
||||
output: &str,
|
||||
is_error: bool,
|
||||
) -> HookRunResult {
|
||||
if let Some(reporter) = self.hook_progress_reporter.as_mut() {
|
||||
self.hook_runner.run_post_tool_use_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
output,
|
||||
is_error,
|
||||
Some(&self.hook_abort_signal),
|
||||
Some(reporter.as_mut()),
|
||||
)
|
||||
} else {
|
||||
self.hook_runner.run_post_tool_use_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
output,
|
||||
is_error,
|
||||
Some(&self.hook_abort_signal),
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn run_post_tool_use_failure_hook(
|
||||
&mut self,
|
||||
tool_name: &str,
|
||||
input: &str,
|
||||
output: &str,
|
||||
) -> HookRunResult {
|
||||
if let Some(reporter) = self.hook_progress_reporter.as_mut() {
|
||||
self.hook_runner.run_post_tool_use_failure_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
output,
|
||||
Some(&self.hook_abort_signal),
|
||||
Some(reporter.as_mut()),
|
||||
)
|
||||
} else {
|
||||
self.hook_runner.run_post_tool_use_failure_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
output,
|
||||
Some(&self.hook_abort_signal),
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn run_turn(
|
||||
&mut self,
|
||||
@@ -314,77 +386,6 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
fn run_pre_tool_use_hook(&mut self, tool_name: &str, input: &str) -> HookRunResult {
|
||||
if let Some(reporter) = self.hook_progress_reporter.as_mut() {
|
||||
self.hook_runner.run_pre_tool_use_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
Some(&self.hook_abort_signal),
|
||||
Some(reporter.as_mut()),
|
||||
)
|
||||
} else {
|
||||
self.hook_runner.run_pre_tool_use_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
Some(&self.hook_abort_signal),
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn run_post_tool_use_hook(
|
||||
&mut self,
|
||||
tool_name: &str,
|
||||
input: &str,
|
||||
output: &str,
|
||||
is_error: bool,
|
||||
) -> HookRunResult {
|
||||
if let Some(reporter) = self.hook_progress_reporter.as_mut() {
|
||||
self.hook_runner.run_post_tool_use_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
output,
|
||||
is_error,
|
||||
Some(&self.hook_abort_signal),
|
||||
Some(reporter.as_mut()),
|
||||
)
|
||||
} else {
|
||||
self.hook_runner.run_post_tool_use_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
output,
|
||||
is_error,
|
||||
Some(&self.hook_abort_signal),
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn run_post_tool_use_failure_hook(
|
||||
&mut self,
|
||||
tool_name: &str,
|
||||
input: &str,
|
||||
output: &str,
|
||||
) -> HookRunResult {
|
||||
if let Some(reporter) = self.hook_progress_reporter.as_mut() {
|
||||
self.hook_runner.run_post_tool_use_failure_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
output,
|
||||
Some(&self.hook_abort_signal),
|
||||
Some(reporter.as_mut()),
|
||||
)
|
||||
} else {
|
||||
self.hook_runner.run_post_tool_use_failure_with_context(
|
||||
tool_name,
|
||||
input,
|
||||
output,
|
||||
Some(&self.hook_abort_signal),
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn compact(&self, config: CompactionConfig) -> CompactionResult {
|
||||
compact_session(&self.session, config)
|
||||
|
||||
@@ -1923,7 +1923,7 @@ fn build_runtime(
|
||||
) -> Result<ConversationRuntime<AnthropicRuntimeClient, CliToolExecutor>, Box<dyn std::error::Error>>
|
||||
{
|
||||
let feature_config = build_runtime_feature_config()?;
|
||||
let runtime = ConversationRuntime::new_with_features(
|
||||
let mut runtime = ConversationRuntime::new_with_features(
|
||||
session,
|
||||
AnthropicRuntimeClient::new(model, enable_tools, emit_output, allowed_tools.clone())?,
|
||||
CliToolExecutor::new(allowed_tools, emit_output),
|
||||
@@ -1931,9 +1931,45 @@ fn build_runtime(
|
||||
system_prompt,
|
||||
feature_config,
|
||||
);
|
||||
if emit_output {
|
||||
runtime = runtime.with_hook_progress_reporter(Box::new(CliHookProgressReporter));
|
||||
}
|
||||
Ok(runtime)
|
||||
}
|
||||
|
||||
struct CliHookProgressReporter;
|
||||
|
||||
impl runtime::HookProgressReporter for CliHookProgressReporter {
|
||||
fn on_event(&mut self, event: &runtime::HookProgressEvent) {
|
||||
match event {
|
||||
runtime::HookProgressEvent::Started {
|
||||
event,
|
||||
tool_name,
|
||||
command,
|
||||
} => eprintln!(
|
||||
"[hook {event_name}] {tool_name}: {command}",
|
||||
event_name = event.as_str()
|
||||
),
|
||||
runtime::HookProgressEvent::Completed {
|
||||
event,
|
||||
tool_name,
|
||||
command,
|
||||
} => eprintln!(
|
||||
"[hook done {event_name}] {tool_name}: {command}",
|
||||
event_name = event.as_str()
|
||||
),
|
||||
runtime::HookProgressEvent::Cancelled {
|
||||
event,
|
||||
tool_name,
|
||||
command,
|
||||
} => eprintln!(
|
||||
"[hook cancelled {event_name}] {tool_name}: {command}",
|
||||
event_name = event.as_str()
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CliPermissionPrompter {
|
||||
current_mode: PermissionMode,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user