Skip to content

tools: add GuardrailProvider protocol for tool call interception#7881

Open
maxpetrusenkoagent wants to merge 3 commits into
microsoft:mainfrom
maxpetrusenkoagent:hermes/oss-pr-2026-06-24-autogen-7405
Open

tools: add GuardrailProvider protocol for tool call interception#7881
maxpetrusenkoagent wants to merge 3 commits into
microsoft:mainfrom
maxpetrusenkoagent:hermes/oss-pr-2026-06-24-autogen-7405

Conversation

@maxpetrusenkoagent

@maxpetrusenkoagent maxpetrusenkoagent commented Jun 24, 2026

Copy link
Copy Markdown

Summary

Implements the GuardrailProvider protocol proposed in issue #7405, enabling
applications to inspect, modify, or block tool calls before they execute.

Changes

New file: autogen_core/tools/_guardrail.py

  • Decision — enum with ALLOW, DENY, MODIFY
  • GuardrailResult — dataclass carrying:
    • decision: Decision
    • reason: str | None — description of the guardrail decision
    • modified_args: Mapping[str, Any] | None — args to pass forward (MODIFY only)
    • metadata: dict[str, Any] — additional context for callers
  • GuardrailProviderruntime_checkable Protocol with:
    async def evaluate(
        *,
        tool_name: str,
        args: Mapping[str, Any],
        agent_name: str | None = None,
        call_id: str | None = None,
        cancellation_token: Any = None,
    ) -> GuardrailResult

Modified: autogen_core/tools/_base.py

  • BaseTool.__init__ accepts optional guardrail_providers: Sequence[GuardrailProvider]
  • BaseTool.add_guardrail(provider) — append to the per-instance chain
  • BaseTool.run_json() evaluates the guardrail chain before executing the tool:
    • ALLOW → pass args to the tool
    • DENY → return "Tool call denied: {reason}" immediately
    • MODIFY → pass modified_args to the tool; chain continues to next guardrail
  • BaseStreamTool.run_json_stream() — same guardrail logic before streaming begins

Modified: autogen_core/tools/_function_tool.py

  • FunctionTool.__init__ accepts and forwards guardrail_providers to BaseTool

Usage example

from autogen_core.tools import FunctionTool, GuardrailResult, Decision

class SQLInjectionGuardrail:
    async def evaluate(
        *, tool_name: str, args: Mapping[str, Any], **kwargs
    ) -> GuardrailResult:
        if "DROP" in args.get("query", "").upper():
            return GuardrailResult(Decision.DENY, reason="SQL injection detected")
        return GuardrailResult(Decision.ALLOW)

tool = FunctionTool(run_sql, description="Run a SQL query")
tool.add_guardrail(SQLInjectionGuardrail())

Tests

14 new tests in test_tools.py covering: allow, deny, modify, chained
evaluation, short-circuit on first DENY, independent per-instance chains,
init-time provider injection, empty-chain overhead, and runtime Protocol
verification.

Closes #7405

maxpetrusenkoagent and others added 3 commits June 24, 2026 01:09
Implements the GuardrailProvider protocol from issue microsoft#7405.

- Decision enum: ALLOW | DENY | MODIFY
- GuardrailResult dataclass: carries decision, optional reason,
  optional modified_args, and optional metadata
- GuardrailProvider Protocol: async evaluate() method with tool_name,
  args, agent_name, call_id, and cancellation_token parameters
- BaseTool: add_guardrail() method, init-time guardrail_providers
  parameter, guardrail evaluation in run_json() and run_json_stream()
  before tool execution; DENY short-circuits with a denial string,
  MODIFY passes revised args to the tool
- FunctionTool: guardrail_providers forwarded to BaseTool.__init__

Closes microsoft#7405

Signed-off-by: maxpetrusenkoagent <max.petrusenko.agent@gmail.com>
@maxpetrusenkoagent maxpetrusenkoagent marked this pull request as ready for review June 28, 2026 04:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: GuardrailProvider protocol for tool call interception

1 participant