PostToolUseEvent

Struct PostToolUseEvent 

Source
pub struct PostToolUseEvent {
    pub tool_name: String,
    pub tool_input: Value,
    pub tool_use_id: String,
    pub tool_result: Value,
    pub history: Vec<Value>,
}
Expand description

Event fired after a tool completes execution, enabling audit, filtering, or validation.

This event provides complete visibility into what a tool did, including both the input parameters and the output result. Use this for auditing, metrics collection, output filtering, or post-execution validation.

§Use Cases

  • Audit logging: Record all tool executions with inputs and outputs for compliance
  • Output filtering: Redact sensitive information from tool results
  • Metrics collection: Track tool performance, success rates, error patterns
  • Result validation: Ensure tool outputs meet quality or safety standards
  • Error handling: Implement custom error recovery or alerting

§Fields

  • tool_name: The name of the tool that was executed
  • tool_input: The parameters that were actually used (may have been modified by PreToolUse hooks)
  • tool_use_id: Unique identifier for this invocation (matches PreToolUseEvent.tool_use_id)
  • tool_result: The result returned by the tool (contains either success data or error info)
  • history: Read-only snapshot of conversation history including this tool’s execution

§Example: Audit Logging

use open_agent::{PostToolUseEvent, HookDecision};

async fn audit_logger(event: PostToolUseEvent) -> Option<HookDecision> {
    // Log all tool executions to your audit system
    let is_error = event.tool_result.get("error").is_some();

    println!(
        "[AUDIT] Tool: {}, ID: {}, Status: {}",
        event.tool_name,
        event.tool_use_id,
        if is_error { "ERROR" } else { "SUCCESS" }
    );

    // Send to external logging service
    // log_to_service(&event).await;

    None // Don't interfere with execution
}

§Example: Sensitive Data Redaction

use open_agent::{PostToolUseEvent, HookDecision};
use serde_json::json;

async fn redact_secrets(event: PostToolUseEvent) -> Option<HookDecision> {
    // Redact API keys from Read tool output
    if event.tool_name == "Read" {
        if let Some(content) = event.tool_result.get("content") {
            if let Some(text) = content.as_str() {
                if text.contains("API_KEY=") {
                    let redacted = text.replace(
                        |c: char| c.is_alphanumeric(),
                        "*"
                    );
                    // Note: PostToolUse hooks typically don't modify results,
                    // but you could log this for security review
                    println!("Warning: Potential API key detected in output");
                }
            }
        }
    }
    None
}

§Note on Modification

While HookDecision theoretically allows modification in PostToolUse hooks, this is rarely used in practice. The tool has already executed, and most agents don’t support modifying historical results. PostToolUse hooks are primarily for observation and auditing.

Fields§

§tool_name: String

Name of the tool that was executed

§tool_input: Value

Input parameters that were actually used (may differ from original if modified by PreToolUse)

§tool_use_id: String

Unique identifier for this tool use (correlates with PreToolUseEvent)

§tool_result: Value

Result returned by the tool - may contain “content” on success or “error” on failure

§history: Vec<Value>

Snapshot of conversation history (read-only) including this tool execution

Implementations§

Source§

impl PostToolUseEvent

Source

pub fn new( tool_name: String, tool_input: Value, tool_use_id: String, tool_result: Value, history: Vec<Value>, ) -> Self

Creates a new PostToolUseEvent.

This constructor is typically called by the agent runtime after tool execution, not by user code. Users receive instances of this struct in their hook handlers.

Trait Implementations§

Source§

impl Clone for PostToolUseEvent

Source§

fn clone(&self) -> PostToolUseEvent

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PostToolUseEvent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more