22
33Hooks let your code see, change, or stop things the agent does.
44
5- Tool and run hooks are wired into the [ SerdesAI] agent pipeline: registered
6- hooks intercept real tool calls and agent runs end to end.
5+ Tool, run, and run-event hooks are wired into the [ SerdesAI] agent
6+ pipeline: registered hooks intercept real tool calls, agent runs, and
7+ streamed run events end to end.
78
89Tool hooks work like game mods.
910Each hook gets an ` original ` function.
@@ -247,6 +248,64 @@ error still propagates to the caller. An outer hook that skips
247248` original ` never reaches this hook, so do not rely on it for cleanup
248249that must run on every path.
249250
251+ ### Intercept streamed events
252+
253+ Run-event hooks fire only on ` run_stream() ` . Each event passes the
254+ registered ` RunEventHook ` s, in registration order, only until one
255+ suppresses it with ` Ok(None) ` or rejects it with ` Err(ToolError) ` ;
256+ a rejection also terminates the stream.
257+
258+ Per event, a hook returns one of three decisions:
259+
260+ - ` Ok(Some(event)) ` publishes it, changed or unchanged.
261+ - ` Ok(None) ` suppresses it. Later hooks and the consumer never see it.
262+ - ` Err(ToolError) ` stops dispatch; the stream ends with
263+ ` Err(AgentRunError::Other) ` .
264+
265+ This hook forwards the events a TUI renders. The consumer still sees
266+ every event:
267+
268+ ``` rust
269+ use reloaded_code_core :: {HookSet , RunEventContext , RunEventHookResult };
270+ use reloaded_code_serdesai :: {RunEvent , RunEventHook };
271+
272+ struct TuiSender { /* channel to the UI thread */ }
273+
274+ impl TuiSender {
275+ /// Stub: cheap, non-blocking send; the UI thread draws.
276+ fn send_to_tui (& self , _event : & RunEvent ) {}
277+ }
278+
279+ struct ForwardToTui {
280+ tui : TuiSender ,
281+ }
282+
283+ impl RunEventHook for ForwardToTui {
284+ fn hook (& self , _ctx : & RunEventContext <'_ >, event : RunEvent ) -> RunEventHookResult {
285+ // Forward only what the TUI renders
286+ match & event {
287+ RunEvent :: TextDelta { .. } | RunEvent :: RunComplete { .. } => {
288+ self . tui. send_to_tui (& event );
289+ }
290+ _ => {}
291+ }
292+ Ok (Some (event ))
293+ }
294+ }
295+
296+ let hooks = HookSet :: builder ()
297+ . run_event_hook (ForwardToTui { tui : TuiSender {} })
298+ . build ();
299+ ```
300+
301+ Hooks run synchronously at token rate; keep per-event work cheap. Each
302+ call sees one event. Text can split across several ` TextDelta ` s, so
303+ buffer cross-event context inside the hook.
304+
305+ Full example: [ serdesai-run-event-hook] rewrites text deltas to
306+ uppercase and suppresses the output-ready milestone
307+ (` cargo run --example serdesai-run-event-hook -p reloaded-code-serdesai --features mock ` ).
308+
250309## Available types
251310
252311### Tool hook types
@@ -272,12 +331,21 @@ that must run on every path.
272331| [ ` RunExecutor ` ] | Final callable used at the end of the run hook chain. |
273332| [ ` RunUsage ` ] | Token usage for a completed run. |
274333
334+ ### Run event hook types
335+
336+ | Type | Purpose |
337+ | ---------------------- | ----------------------------------------------------- |
338+ | [ ` RunEventHook ` ] | Observes, rewrites, or suppresses one streamed event. |
339+ | [ ` RunEventContext ` ] | Agent and model names for the event's stream. |
340+ | [ ` RunEvent ` ] | Framework-owned event yielded by a run stream. |
341+ | [ ` RunEventHookResult ` ] | Publish, rewrite, suppress, or Err(ToolError). |
342+
275343### Container types
276344
277- | Type | Purpose |
278- | ------------------ | ------------------------------------------------- |
279- | [ ` HookSet ` ] | Stores tool hooks, run hooks, and compact events. |
280- | [ ` HookSetBuilder ` ] | Builder for [ ` HookSet ` ] . |
345+ | Type | Purpose |
346+ | ------------------ | ----------------------------------------------------------- |
347+ | [ ` HookSet ` ] | Stores tool, run, and run-event hooks, plus compact events. |
348+ | [ ` HookSetBuilder ` ] | Builder for [ ` HookSet ` ] . |
281349
282350## How tool hooks stack
283351
@@ -340,6 +408,10 @@ passes `HookSet::default()`.
340408- ** Empty fast path.** ` dispatch_tool ` calls the real tool directly when you
341409 set no hooks.
342410
411+ - ** Mode-scoped run hooks.** ` RunHook ` fires only on ` run() ` ;
412+ ` RunEventHook ` fires only on ` run_stream() ` . Each hook point stays
413+ inert on the other path.
414+
343415
344416[ `ToolHook` ] : https://docs.rs/reloaded-code-core/latest/reloaded_code_core/trait.ToolHook.html
345417[ `ToolOriginal` ] : https://docs.rs/reloaded-code-core/latest/reloaded_code_core/struct.ToolOriginal.html
@@ -356,8 +428,13 @@ passes `HookSet::default()`.
356428[ `RunOutput` ] : https://docs.rs/reloaded-code-core/latest/reloaded_code_core/struct.RunOutput.html
357429[ `RunExecutor` ] : https://docs.rs/reloaded-code-core/latest/reloaded_code_core/trait.RunExecutor.html
358430[ `RunUsage` ] : https://docs.rs/reloaded-code-core/latest/reloaded_code_core/struct.RunUsage.html
431+ [ `RunEventHook` ] : https://docs.rs/reloaded-code-core/latest/reloaded_code_core/trait.RunEventHook.html
432+ [ `RunEventContext` ] : https://docs.rs/reloaded-code-core/latest/reloaded_code_core/struct.RunEventContext.html
433+ [ `RunEvent` ] : https://docs.rs/reloaded-code-core/latest/reloaded_code_core/enum.RunEvent.html
434+ [ `RunEventHookResult` ] : https://docs.rs/reloaded-code-core/latest/reloaded_code_core/type.RunEventHookResult.html
359435[ SerdesAI ] : https://crates.io/crates/serdes-ai
360436[ serdesai-tool-hook ] : https://github.com/Reloaded-Project/ReloadedCode/blob/main/src/reloaded-code-serdesai/examples/hooks/tool/serdesai-tool-hook.rs
361437[ serdesai-tool-block ] : https://github.com/Reloaded-Project/ReloadedCode/blob/main/src/reloaded-code-serdesai/examples/hooks/tool/serdesai-tool-block.rs
362438[ serdesai-tool-chain ] : https://github.com/Reloaded-Project/ReloadedCode/blob/main/src/reloaded-code-serdesai/examples/hooks/tool/serdesai-tool-chain.rs
363439[ serdesai-run-hook ] : https://github.com/Reloaded-Project/ReloadedCode/blob/main/src/reloaded-code-serdesai/examples/hooks/run/serdesai-run-hook.rs
440+ [ serdesai-run-event-hook ] : https://github.com/Reloaded-Project/ReloadedCode/blob/main/src/reloaded-code-serdesai/examples/hooks/run/serdesai-run-event-hook.rs
0 commit comments