pub enum HookResult {
Continue,
Block {
reason: String,
},
Inject {
content: String,
},
Confirm {
message: String,
sources: Vec<String>,
generations: Vec<u64>,
tool: Option<String>,
modified_input: Option<Value>,
modified_by: Vec<String>,
},
Modify {
input: Value,
},
Replace {
output: String,
},
ContextPhase {
phase: String,
},
}Expand description
What an extension handler returns after processing a hook event.
The runtime resolves multiple handlers by precedence:
- For
before_tool_callonlyBlockstops the handler chain.Modifyrewrites the input that later handlers see;Confirmis merged and resolved after the whole chain (aModifyafter it is ignored). Injectresults are accumulated forbefore_message.Continueis the no-op default — processing continues normally.
Variants§
Continue
Allow execution to proceed unchanged.
Block
Prevent the hooked operation. The reason is surfaced to the user.
Inject
Inject context — the extension provides text for the current request.
Placement depends on the hook (#297): on_session_start content is
appended to the system prompt (session-stable, cache-safe);
before_message content is attached to the newest user message on the
outgoing request as an ephemeral trailing block positioned AFTER the
conversational cache marker (per-turn, uncached tail, cache-neutral).
Confirm
Ask the runtime to get explicit user confirmation before proceeding. Only valid on before_tool_call hooks.
sources / tool are host-stamped by HookBus::emit (the extension
id(s) that asked, and the tool name). They are never read from or
written to the extension wire format, so an extension cannot claim to
be another extension. The “Allow all” latch is keyed by sources.
Fields
generations: Vec<u64>Host-set load generation of each source (parallel to sources;
missing entries mean 0). Part of the latch key, so a plugin
reinstalled under the same id starts unlatched.
Modify
Replace the tool input before execution (structured JSON args).
Only valid on before_tool_call hooks. The output-side counterpart is
HookResult::Replace. Does not stop the chain: later handlers see
(and may block or confirm) the modified input.
Replace
Replace the tool output after execution (flat string), before it
enters history. Only valid on after_tool_call hooks. The input-side
counterpart is HookResult::Modify — distinct name because the payload
is an unstructured String, not structured Value. Enables native
output transforms (compression, redaction, summarization) by extensions.
The first transform stops the handler chain.
ContextPhase
Advisory work-phase report for the host’s automatic context
management. Only valid on on_message_complete, and only honoured
when the extension additionally holds session.lifecycle. Semantics
are identical to the model calling context_checkpoint with this
phase and no note: the host may roll the context window over at the
next task boundary. It is a lower-authority report — never capacity,
permission, or history authority — and does not stop the handler
chain (other observers still run; the first valid report wins).
phase is parsed host-side with WorkPhase::parse; unknown strings
are ignored with a warning.
Implementations§
Trait Implementations§
Source§impl Clone for HookResult
impl Clone for HookResult
Source§impl Debug for HookResult
impl Debug for HookResult
Source§impl Default for HookResult
impl Default for HookResult
Source§impl<'de> Deserialize<'de> for HookResult
impl<'de> Deserialize<'de> for HookResult
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for HookResult
impl PartialEq for HookResult
Source§impl Serialize for HookResult
impl Serialize for HookResult
impl StructuralPartialEq for HookResult
Auto Trait Implementations§
impl Freeze for HookResult
impl RefUnwindSafe for HookResult
impl Send for HookResult
impl Sync for HookResult
impl Unpin for HookResult
impl UnsafeUnpin for HookResult
impl UnwindSafe for HookResult
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.