feat(redaction): add event-level redact_event hook#41
Open
naji247 wants to merge 2 commits into
Open
Conversation
Add a redact_event option to AgentCatOptions that receives the full Event object before publishing, complementing the existing string-level redact_sensitive_information hook. Consumers can inspect event metadata (resource_name, event_type, parameters, response, etc.) to make context-aware redaction decisions, return a modified event, or return None to drop the event entirely. - New EventRedactionFunction type; Event and EventRedactionFunction are now exported from the package root - Hook runs before string-level redaction, so it sees raw values; string redaction, sanitization, and truncation still run on its output - System-managed fields (id, session_id, project_id, event_type, timestamp) are restored if the hook alters them - Hook errors drop the event and log, matching existing redaction semantics - Attached centrally in publish_event, covering every event producer
kashishhora
approved these changes
Jul 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Redaction decisions often need more context than a single string. The existing
redact_sensitive_informationhook is applied blindly to every string field in an event, so consumers can't tell which tool produced a value, what type of event is being published, or which field a string belongs to.This PR adds a new event-level redaction hook,
redact_event, alongside the existing string-level hook. It receives the fullEventobject —resource_name,event_type,parameters,response,user_intent, and the rest — and returns a modified event, orNoneto drop the event entirely.Behavior
Callable[[Event], Event | None | Awaitable[Event | None]]— sync or async, exported asEventRedactionFunction.Eventis now also exported from the package root.redact_eventruns first in the queue pipeline and sees raw, unredacted values with full event context.redact_sensitive_information(if configured), sanitization, and truncation all run on its output, so the string-level scrubber remains the last line of defense.Nonedrops the event. If the hook raises, the event is dropped and the error is logged to~/agentcat.log— the same fail-closed semantics as the existing string-level hook.id,session_id,project_id,event_type, andtimestampare restored if the hook changes or removes them, protecting session and project attribution. Everything else is fully consumer-controlled, and fields the hook clears stay cleared.Behavior note worth knowing
The string-level
redact_sensitive_informationhook currently never fires on the live publish path — the recursive walker doesn't descend into Pydantic event models (tracked by the xfail suite intests/e2e/official/test_redaction_http.py). The new event-level hook operates on the Pydantic model directly and works on the live path today, so it also serves as a working redaction mechanism until that bug is fixed. The structural ordering (event hook first, string hook second) is preserved for when it is.Test plan
apply_event_redactionhelper: sync/async hooks,Nonedrops, cleared-field honoring, system-managed field restoration, internal function fields hidden from the hook withredaction_fnpreserved, error propagation, same-object mutation for pipeline observers (tests/test_redaction.py)track()options viapublish_event, hook rewrite published, drop-on-None, drop-on-raise, ordering relative to string redaction (tests/test_event_queue.py)resource_name, drop-on-None with other events still publishing, and a raising hook dropping only the affected event while the server keeps serving (tests/e2e/official/test_redact_event_http.py)ruffandmypy --strictat their pre-existing baselines with no new findings