Skip to content

feat(autogen): add native GovernanceInterventionHandler via AutoGen v0.4+ hooks#1591

Merged
imran-siddique merged 1 commit intomicrosoft:mainfrom
miyannishar:feat/autogen-native-hooks
Apr 30, 2026
Merged

feat(autogen): add native GovernanceInterventionHandler via AutoGen v0.4+ hooks#1591
imran-siddique merged 1 commit intomicrosoft:mainfrom
miyannishar:feat/autogen-native-hooks

Conversation

@miyannishar
Copy link
Copy Markdown
Collaborator

Summary

Replaces fragile monkey-patching in the AutoGen adapter with AutoGen v0.4+'s native InterventionHandler system (on_send, on_publish, on_response).

Resolves #1590

Changes

New: GovernanceInterventionHandler class

Intercepts all message traffic in the AutoGen runtime:

Hook Governance Action
on_send Tool call governance (FunctionCall allowlist, blocked-pattern scan, Cedar/OPA gate, max call count); general content filtering and PII detection
on_publish Broadcast message governance — blocked patterns and PII detection
on_response Output content filtering, blocked-pattern scan, post_execute drift detection

New: AutoGenKernel.as_handler() factory

kernel = AutoGenKernel(policy=GovernancePolicy(
    blocked_patterns=["DROP TABLE"],
    allowed_tools=["search", "calculator"],
))
handler = kernel.as_handler()
runtime = SingleThreadedAgentRuntime(
    intervention_handlers=[handler],
)

Deprecated: govern(), wrap(), and module-level govern()

All now emit DeprecationWarning pointing to as_handler(). Full backward compatibility maintained — all 18 existing regression tests pass unchanged.

Export

AutoGenGovernanceHandler exported from agent_os.integrations.

Testing

  • 51 new tests covering all three hook types, tool governance, PII detection, Cedar/OPA integration, deprecation warnings, content extraction, and backward compatibility
  • 18 existing regression tests pass unchanged (test_adapter_quality.py, test_deep_integrations.py)
  • Tests use stub autogen_core module since AutoGen is not installed in CI

Design Decisions

  1. Runtime-level interception: Intervention handlers see ALL message traffic, not just method calls on specific agents — broader governance coverage
  2. DropMessage semantics: Uses AutoGen's native DropMessage sentinel to block violations, matching the framework's expected behavior
  3. PII detection everywhere: Extends PII scanning to all hooks (send, publish, response), not just state changes
  4. Graceful degradation: If autogen_core is unavailable, as_handler() raises RuntimeError while govern() continues to work
  5. Pattern parity: as_handler() mirrors ADK's as_plugin(), OpenAI's as_hooks(), and CrewAI's as_hooks()

Related

…0.4+ hooks

Replace fragile monkey-patching with AutoGen's native intervention
handler system (DefaultInterventionHandler with on_send, on_publish,
on_response) introduced in AutoGen v0.4+.

Changes:
- Add GovernanceInterventionHandler class with three hooks:
  - on_send: tool call governance, content filtering, PII detection
  - on_publish: broadcast message governance
  - on_response: output content filtering, drift detection
- Add AutoGenKernel.as_handler() factory method as the recommended
  integration path
- Deprecate govern() and wrap() with DeprecationWarning pointing to
  as_handler()
- Export AutoGenGovernanceHandler from integrations package
- Add 51 new tests covering all three hook types, Cedar/OPA integration,
  deprecation warnings, PII detection, and backward compatibility
- All 18 existing AutoGen regression tests pass unchanged
@github-actions
Copy link
Copy Markdown

🤖 AI Agent: docs-sync-checker — Docs Sync

Docs Sync

  • GovernanceInterventionHandler in autogen_adapter.py -- missing docstring for on_send, on_publish, and on_response methods.
  • README.md -- update required to reflect the new as_handler() method and deprecation of govern() and wrap().
  • CHANGELOG.md -- missing entry for the introduction of GovernanceInterventionHandler, as_handler() method, and deprecation of legacy methods.

@github-actions github-actions Bot added the size/XL Extra large PR (500+ lines) label Apr 29, 2026
@github-actions
Copy link
Copy Markdown

🤖 AI Agent: breaking-change-detector — API Compatibility

API Compatibility

Severity Change Impact
High Deprecated govern() and wrap() methods in AutoGenKernel Existing code using these methods will need to migrate to the new as_handler() method.
High Deprecated module-level govern() function Code relying on this function will need to switch to AutoGenKernel.as_handler().
High as_handler() raises RuntimeError if autogen_core is unavailable Environments without autogen_core will break when attempting to use as_handler().

@github-actions
Copy link
Copy Markdown

🤖 AI Agent: security-scanner — View details

No security issues found.

@github-actions
Copy link
Copy Markdown

🤖 AI Agent: code-reviewer — Review Summary

Review Summary

This pull request introduces a significant enhancement to the microsoft/agent-governance-toolkit by replacing the legacy monkey-patching approach with AutoGen v0.4+'s native InterventionHandler system. The new GovernanceInterventionHandler class provides runtime-level interception of message traffic, enabling robust governance for tool calls, content filtering, PII detection, and policy enforcement. The PR also maintains backward compatibility with the deprecated govern() and wrap() methods, ensuring a smooth transition for existing users.

While the implementation is well-structured and includes comprehensive test coverage, there are a few areas that require attention to ensure security, correctness, and maintainability.


CRITICAL

  1. Potential Bypass of Governance Rules in on_send:

    • The on_send method relies on the _extract_content method to extract text content from messages. However, the _extract_content method only checks for str, dict, or objects with a content attribute. If a message is passed in an unexpected format (e.g., a custom object without a content attribute), it could bypass governance checks.
    • Action: Ensure that _extract_content handles all possible message formats or explicitly raises an error for unsupported types. Consider adding a fallback mechanism to log and block messages with unrecognized formats.
  2. Thread Safety of GovernanceInterventionHandler:

    • The GovernanceInterventionHandler uses a shared ExecutionContext (self._ctx) to track state, such as call_count. If the GovernanceInterventionHandler is used in a multi-threaded or concurrent environment, this shared state could lead to race conditions.
    • Action: Either make GovernanceInterventionHandler explicitly single-threaded (e.g., by documenting this constraint) or refactor the implementation to ensure thread safety (e.g., by using thread-local storage or locks).
  3. Cedar/OPA Policy Evaluation:

    • The pre_execute and post_execute methods rely on the Cedar/OPA policy evaluator. However, there is no validation of the inputs or outputs of these methods. If the policy evaluator is misconfigured or compromised, it could lead to incorrect governance decisions.
    • Action: Add validation for the inputs and outputs of pre_execute and post_execute to ensure they conform to expected formats and values. Log any unexpected behavior for auditing purposes.

WARNING

  1. Deprecation of govern() and wrap():
    • The PR deprecates the govern() and wrap() methods, emitting DeprecationWarning and pointing users to the new as_handler() method. While backward compatibility is maintained, the eventual removal of these methods in v1.0 will be a breaking change.
    • Action: Clearly document the deprecation timeline in the project documentation and release notes. Provide migration guides to help users transition to the new API.

SUGGESTIONS

  1. Error Handling in as_handler():

    • The as_handler() method raises a RuntimeError if autogen_core is unavailable. While this is appropriate, consider providing a more descriptive error message that includes guidance on how to install or upgrade autogen_core.
  2. Logging Improvements:

    • The logging in GovernanceInterventionHandler is thorough, but it could benefit from additional context, such as the recipient or sender of the message, where applicable. This would aid in debugging and auditing.
  3. Test Coverage for Edge Cases:

    • While the test suite is comprehensive, it would be beneficial to add tests for edge cases, such as:
      • Messages with unexpected formats (e.g., custom objects without a content attribute).
      • Concurrent execution of GovernanceInterventionHandler to verify thread safety.
      • Scenarios where pre_execute or post_execute return unexpected results.
  4. Type Annotations:

    • The new methods and classes have some type annotations, but there are still areas where type hints are missing or could be more specific (e.g., Any for message, message_context, and recipient in on_send).
  5. Documentation:

    • The docstrings are well-written, but consider adding more detailed examples for the GovernanceInterventionHandler and as_handler() usage, especially for complex scenarios involving multiple agents and policies.
  6. Performance Considerations:

    • The matches_pattern method is called multiple times in the on_send, on_publish, and on_response hooks. If the blocked patterns list is large, this could impact performance.
    • Action: Consider optimizing the pattern matching logic, such as by pre-compiling a single regex pattern that combines all blocked patterns.

Final Assessment

The PR introduces a robust and much-needed improvement to the governance system by leveraging AutoGen's native InterventionHandler hooks. The implementation is well-structured and includes extensive test coverage, ensuring a high level of confidence in the changes. However, there are critical areas that need to be addressed to ensure security and thread safety. Additionally, the deprecation of existing methods should be carefully managed to avoid breaking changes for users.

Once the critical issues are resolved, this PR will be a strong candidate for merging.

@github-actions
Copy link
Copy Markdown

🤖 AI Agent: test-generator — `agent_os/integrations/autogen_adapter.py`

Test Coverage Analysis

agent_os/integrations/autogen_adapter.py

  • Existing coverage:
    • The new GovernanceInterventionHandler class is extensively tested in the newly added test_autogen_hooks.py file.
    • Tests cover:
      • on_send, on_publish, and on_response hooks.
      • Tool governance (allowlist, blocked patterns, max calls).
      • Content filtering (blocked patterns, PII detection).
      • Cedar/OPA policy evaluation integration.
      • Deprecation warnings for legacy methods (govern, wrap).
      • Backward compatibility with legacy monkey-patching.
  • Missing coverage:
    • Edge cases for on_send:
      • Handling malformed FunctionCall objects (e.g., missing name or arguments attributes).
      • Behavior when allowed_tools is empty or None.
      • Handling of extremely large tool_args strings.
    • Edge cases for on_publish:
      • Broadcast messages with deeply nested content structures.
      • Handling of malformed messages (e.g., missing content attribute).
    • Edge cases for on_response:
      • Responses with non-string content (e.g., binary data or complex objects).
      • Drift detection failures with ambiguous reasons.
    • Graceful degradation:
      • Behavior when autogen_core is partially available (e.g., missing DropMessage but FunctionCall exists).
      • Behavior when autogen_core is unavailable but legacy methods are invoked.
  • Suggested test cases:
    1. test_on_send_malformed_function_call — Verify that on_send gracefully handles FunctionCall objects missing required attributes (name, arguments).
    2. test_on_send_empty_allowed_tools — Test on_send behavior when allowed_tools is empty or None.
    3. test_on_send_large_tool_args — Test on_send with extremely large tool_args strings to ensure performance and correctness.
    4. test_on_publish_nested_content — Verify on_publish handles deeply nested content structures correctly.
    5. test_on_publish_malformed_message — Test on_publish behavior with malformed messages missing the content attribute.
    6. test_on_response_non_string_content — Verify on_response handles responses with non-string content gracefully.
    7. test_on_response_drift_detection_failure — Test on_response behavior when drift detection fails with ambiguous reasons.
    8. test_graceful_degradation_partial_autogen_core — Verify behavior when autogen_core is partially available (e.g., missing DropMessage).
    9. test_graceful_degradation_no_autogen_core — Test behavior when autogen_core is unavailable but legacy methods (govern, wrap) are invoked.

agent_os/tests/test_autogen_hooks.py

  • Existing coverage:
    • Covers all major functionality of GovernanceInterventionHandler:
      • on_send, on_publish, and on_response hooks.
      • Tool governance, content filtering, Cedar/OPA integration.
      • Deprecation warnings for legacy methods.
      • Backward compatibility with legacy monkey-patching.
  • Missing coverage:
    • Edge cases for malformed inputs, ambiguous policy evaluation results, and partial framework availability.
  • Suggested test cases:
    1. test_on_send_malformed_function_call — Verify on_send handles malformed FunctionCall objects.
    2. test_on_publish_nested_content — Test on_publish with deeply nested content structures.
    3. test_on_response_drift_detection_failure — Verify on_response behavior when drift detection fails ambiguously.
    4. test_graceful_degradation_partial_autogen_core — Test behavior when autogen_core is partially available.

Summary

The new GovernanceInterventionHandler is well-covered by existing tests, but additional edge cases focusing on malformed inputs, ambiguous policy results, and partial framework availability would further strengthen test coverage.

@github-actions
Copy link
Copy Markdown

PR Review Summary

Check Status Details
🔍 Code Review ❌ Failed Issues detected
🛡️ Security Scan ✅ Completed Analysis complete
🔄 Breaking Changes ❌ Failed Issues detected
📝 Docs Sync ✅ Completed Analysis complete
🧪 Test Coverage ⚠️ Warning See details

Verdict: ❌ Changes needed

Copy link
Copy Markdown
Member

@imran-siddique imran-siddique left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: AutoGen GovernanceInterventionHandler

Good deprecation path and documentation, @miyannishar. This one has a few protocol-level issues that will cause runtime failures:

Blocking

1. Must inherit from DefaultInterventionHandler
The class is standalone with no base class. AutoGen's runtime performs isinstance checks against the InterventionHandler protocol. Without inheritance, the handler may silently fail to register. Follow the ADK adapter pattern:
python if _INTERVENTION_AVAILABLE: class GovernanceInterventionHandler(DefaultInterventionHandler): ... else: class GovernanceInterventionHandler: ...

2. on_response signature is wrong
AutoGen's protocol: on_response(message, *, sender: AgentId, recipient: AgentId | None)
PR implements: on_response(message, *, message_context=None, sender=None)

Missing recipient will cause TypeError at runtime. message_context is not a parameter of on_response in the protocol (it's only on on_send/on_publish).

3. on_send/on_publish make required protocol params optional
AutoGen always passes message_context and recipient/sender as keyword arguments. Defaulting to None masks integration errors. Match the protocol signatures exactly.

Security

4. Missing PII detection in on_response
PR description claims "PII detection everywhere" but on_response omits the _PII_PATTERNS scan that on_send and on_publish both perform. Agent responses with SSNs or API keys pass through unblocked.

Warnings

5. Single shared ExecutionContext across all agents
One _ctx is shared across all agents in the runtime. max_tool_calls=5 becomes a runtime-wide budget, not per-agent. Document this as intentional or create per-agent contexts.

6. Test helper uses deprecated asyncio.get_event_loop()
Use asyncio.run() to match other test files.

The protocol mismatches (#1, #2, #3) are the main blockers, as they'll cause runtime failures.

Copy link
Copy Markdown
Member

@imran-siddique imran-siddique left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated review (condensed):

TL;DR: 3 blockers (protocol mismatches that will cause runtime failures).

# Sev Issue Where
1 Block Must inherit DefaultInterventionHandler -- runtime does isinstance checks class definition
2 Block on_response signature wrong: missing recipient, has phantom message_context -- will TypeError on_response
3 Block on_send/on_publish default required params to None -- masks integration errors on_send, on_publish
4 Sec on_response omits PII scan despite PR claiming "PII detection everywhere" on_response
5 Warn Shared ExecutionContext makes max_tool_calls runtime-global, not per-agent __init__

#1: Use conditional inheritance pattern from ADK adapter.

#2: Match protocol: on_response(message, *, sender, recipient).

#3: Match protocol signatures exactly for forward compat.

#4: Add _PII_PATTERNS scan to on_response like on_send/on_publish have.

Copy link
Copy Markdown
Member

@imran-siddique imran-siddique left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving native hooks migration.

@imran-siddique imran-siddique merged commit 442d252 into microsoft:main Apr 30, 2026
13 of 14 checks passed
imran-siddique pushed a commit to imran-siddique/agent-governance-toolkit that referenced this pull request May 4, 2026
…0.4+ hooks (microsoft#1591)

Replace fragile monkey-patching with AutoGen's native intervention
handler system (DefaultInterventionHandler with on_send, on_publish,
on_response) introduced in AutoGen v0.4+.

Changes:
- Add GovernanceInterventionHandler class with three hooks:
  - on_send: tool call governance, content filtering, PII detection
  - on_publish: broadcast message governance
  - on_response: output content filtering, drift detection
- Add AutoGenKernel.as_handler() factory method as the recommended
  integration path
- Deprecate govern() and wrap() with DeprecationWarning pointing to
  as_handler()
- Export AutoGenGovernanceHandler from integrations package
- Add 51 new tests covering all three hook types, Cedar/OPA integration,
  deprecation warnings, PII detection, and backward compatibility
- All 18 existing AutoGen regression tests pass unchanged

Co-authored-by: Nishar <you@example.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Extra large PR (500+ lines) tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AutoGen adapter: use native InterventionHandler instead of govern() monkey-patching

2 participants