intutic_clawde.gate.adapters.autogen
Microsoft AutoGen adapter: IntuticInterventionHandler.
AutoGen (autogen-core/autogen-agentchat/autogen-ext, 0.4+) documents an InterventionHandler protocol — on_send/on_publish/on_response — attached via SingleThreadedAgentRuntime(intervention_handlers=[...]). Returning the sentinel type DropMessage from on_send drops the message before the recipient ever sees it; the runtime raises autogen_core.exceptions.MessageDroppedException back to the sender's await runtime.send_message(...) call. IntuticInterventionHandler below subclasses DefaultInterventionHandler and overrides on_send to veto a FunctionCall message exactly that way.
Verified live (not inferred from docs) by installing autogen-core==0.7.5/autogen-agentchat==0.7.5/autogen-ext==0.7.5 in a scratch venv and reading autogen_core._intervention, autogen_core._single_threaded_agent_runtime, and autogen_agentchat.agents._assistant_agent directly, plus driving the real runtime end to end (not just reading source):
FunctionCallis a plain dataclass —id: str,arguments: str(a JSON-encoded string, same shape as the OpenAI Agents SDK adapter'stool_arguments),name: str.SingleThreadedAgentRuntime._process_nextcallshandler.on_send(message, message_context=..., recipient=...)for every registered handler, in order, BEFORE the message is delivered. ReturningDropMessage(the class itself, or an instance — both are accepted) setsMessageDroppedException()on the sender's future and returns WITHOUT delivering the message. This was confirmed by actually registering a handler, callingruntime.send_message(FunctionCall(...), ...), and observing the awaited call raiseMessageDroppedException— not just reading that the code path exists.- The plan that scoped this adapter proposed
ToolException(call_id=...)as an alternative veto (raising, rather than returningDropMessage) — that class does not exist inautogen_coreat this version (checked bothautogen_coreandautogen_core.tools;autogen_core.exceptionsexports onlyCantHandleException,MessageDroppedException,NotAccessibleError,UndeliverableException).DropMessageis the only confirmed veto point and the one this adapter uses.
Important, load-bearing limitation — read before wiring this in. The plan that scoped this adapter flagged on_send as covering only "RUNTIME-ROUTED messages" and specifically not "in-process AssistantAgent reflection paths." Reading autogen_agentchat.agents._assistant_agent confirms the gap is wider than that phrasing suggests: AssistantAgent — the class every AutoGen tutorial and most real usage builds on — does not call runtime.send_message for its OWN tool calls AT ALL. Its _execute_tool_call (and the _execute_tool_calls that drives it) call workbench.call_tool_stream(...)/handoff_tool.run_json(...) directly, in-process, entirely bypassing the AgentRuntime message-passing this handler intercepts. InterventionHandler.on_send only sees messages that are explicitly routed through runtime.send_message/publish_message — the lower-level, core-API pattern where one custom RoutedAgent dispatches a FunctionCall to another agent (or a ToolAgent) as an actual runtime message. That pattern exists and is documented, but it is not what AssistantAgent does by default, and most AutoGen application code never constructs a runtime-routed tool-call message by hand.
Practically: if the application under governance uses plain AssistantAgent (or ChatAgent/Swarm team patterns built on it) with a Workbench or a plain tool list, IntuticInterventionHandler sees NOTHING — every tool call that agent makes is invisible to it. For that (the common) case, govern the tool objects themselves before handing them to AssistantAgent: wrap each plain tool function with @guard (from intutic_clawde.gate.framework) before constructing the FunctionTool/before adding it to a Workbench, the same way CrewAI and AutoGen tools were already documented as "plain callables — @guard/guard_tools already govern them" prior to this module existing (see framework.py's module doc). This handler is for the narrower, still-real case: a custom multi-agent system built directly on AgentRuntime/RoutedAgent that dispatches FunctionCall messages between agents explicitly. autogen_workbench.py covers the AssistantAgent gap in-process. Microsoft Agent Framework, the AutoGen + Semantic Kernel successor, has its own adapter (agent_framework.py), not this one.
Optional import: importing this module never fails even without autogen-core installed. Only instantiating IntuticInterventionHandler requires it — pip install intutic-clawde[autogen].
Classes
IntuticInterventionHandler
class IntuticInterventionHandler(*, gate: Optional[Gate] = None)Bases: DefaultInterventionHandler
AutoGen InterventionHandler — vetoes a runtime-routed FunctionCall.
Usage:
from autogen_core import SingleThreadedAgentRuntime
from intutic_clawde.gate.adapters.autogen import IntuticInterventionHandler
runtime = SingleThreadedAgentRuntime(
intervention_handlers=[IntuticInterventionHandler()]
)See this module's doc for the load-bearing limitation: this only sees FunctionCall messages explicitly sent via runtime.send_message/ publish_message, not AssistantAgent's own (in-process) tool-call path.
On deny, returns DropMessage — the runtime turns that into a MessageDroppedException on the SENDER's send_message future, so the call never reaches its recipient, matching every other adapter's "deny happens before the tool body runs" contract. Non-FunctionCall messages (and messages this handler was not asked to evaluate) pass through unchanged, exactly like DefaultInterventionHandler.
Methods
IntuticInterventionHandler.on_send()
async def on_send(message: Any, *, message_context: Any, recipient: Any) -> Any