Skip to content

v0.3.0: Pre-Execution Hooks

Choose a tag to compare

@flyersworder flyersworder released this 28 Mar 09:50
· 94 commits to main since this release

What's New

Pre-Execution Hooks — User-defined governance logic that runs before and after every constraint check, across all 5 integrations.

Added

  • CheckContext, HookResult, CheckHook types for custom policy governance
  • pre_check_hooks and post_check_hooks on ContractEnforcer
  • metadata parameter on check_constraints() (backward-compatible)
  • Hook actions: WARN/THROTTLE (informational) and SOFT_STOP/HARD_STOP (blocking)
  • Integration metadata pass-through from LiteLLM, LangChain, LangGraph, Google ADK, and Claude Agent SDK
  • Post-check hooks are observational only (cannot block)
  • 23 new tests, 646+ total passing

Changed

  • Claude Agent SDK aexecute() now routes constraint checks through enforcer
  • check_constraints() accepts optional metadata dict (fully backward-compatible)

Quick Example

from agent_contracts import (
    Contract, ContractedLLM, CheckContext, HookResult,
    EnforcementAction, ResourceConstraints,
)

def topic_guard(ctx: CheckContext) -> HookResult:
    messages = ctx.metadata.get("messages", [])
    if any("forbidden" in str(m) for m in messages):
        return HookResult(
            allow=False,
            reason="Off-topic request",
            action=EnforcementAction.HARD_STOP,
        )
    return HookResult()

contract = Contract(id="guarded", resources=ResourceConstraints(tokens=10000))
with ContractedLLM(contract) as llm:
    llm.enforcer.add_pre_check_hook(topic_guard)
    # Hooks fire on every LLM call, across all integrations

Documentation

Full Changelog: v0.2.0...v0.3.0