mirror of
https://github.com/lWolvesl/claw-code.git
synced 2026-04-02 19:11:51 +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,
|
compact_session, estimate_session_tokens, CompactionConfig, CompactionResult,
|
||||||
};
|
};
|
||||||
use crate::config::RuntimeFeatureConfig;
|
use crate::config::RuntimeFeatureConfig;
|
||||||
use crate::hooks::{HookAbortSignal, HookRunResult, HookRunner};
|
use crate::hooks::{HookAbortSignal, HookProgressReporter, HookRunResult, HookRunner};
|
||||||
use crate::permissions::{
|
use crate::permissions::{
|
||||||
PermissionContext, PermissionOutcome, PermissionPolicy, PermissionPrompter,
|
PermissionContext, PermissionOutcome, PermissionPolicy, PermissionPrompter,
|
||||||
};
|
};
|
||||||
@@ -100,6 +100,7 @@ pub struct ConversationRuntime<C, T> {
|
|||||||
usage_tracker: UsageTracker,
|
usage_tracker: UsageTracker,
|
||||||
hook_runner: HookRunner,
|
hook_runner: HookRunner,
|
||||||
hook_abort_signal: HookAbortSignal,
|
hook_abort_signal: HookAbortSignal,
|
||||||
|
hook_progress_reporter: Option<Box<dyn HookProgressReporter>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, T> ConversationRuntime<C, T>
|
impl<C, T> ConversationRuntime<C, T>
|
||||||
@@ -171,6 +172,77 @@ where
|
|||||||
self
|
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)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub fn run_turn(
|
pub fn run_turn(
|
||||||
&mut self,
|
&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]
|
#[must_use]
|
||||||
pub fn compact(&self, config: CompactionConfig) -> CompactionResult {
|
pub fn compact(&self, config: CompactionConfig) -> CompactionResult {
|
||||||
compact_session(&self.session, config)
|
compact_session(&self.session, config)
|
||||||
|
|||||||
@@ -1923,7 +1923,7 @@ fn build_runtime(
|
|||||||
) -> Result<ConversationRuntime<AnthropicRuntimeClient, CliToolExecutor>, Box<dyn std::error::Error>>
|
) -> Result<ConversationRuntime<AnthropicRuntimeClient, CliToolExecutor>, Box<dyn std::error::Error>>
|
||||||
{
|
{
|
||||||
let feature_config = build_runtime_feature_config()?;
|
let feature_config = build_runtime_feature_config()?;
|
||||||
let runtime = ConversationRuntime::new_with_features(
|
let mut runtime = ConversationRuntime::new_with_features(
|
||||||
session,
|
session,
|
||||||
AnthropicRuntimeClient::new(model, enable_tools, emit_output, allowed_tools.clone())?,
|
AnthropicRuntimeClient::new(model, enable_tools, emit_output, allowed_tools.clone())?,
|
||||||
CliToolExecutor::new(allowed_tools, emit_output),
|
CliToolExecutor::new(allowed_tools, emit_output),
|
||||||
@@ -1931,9 +1931,45 @@ fn build_runtime(
|
|||||||
system_prompt,
|
system_prompt,
|
||||||
feature_config,
|
feature_config,
|
||||||
);
|
);
|
||||||
|
if emit_output {
|
||||||
|
runtime = runtime.with_hook_progress_reporter(Box::new(CliHookProgressReporter));
|
||||||
|
}
|
||||||
Ok(runtime)
|
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 {
|
struct CliPermissionPrompter {
|
||||||
current_mode: PermissionMode,
|
current_mode: PermissionMode,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user