One tool call can drop a table, delete a namespace, or wire money. Aegmis puts a human approval gate in front of your agent's riskiest actions — decided by policy, approved in Slack, and logged end to end. Works with LangGraph, OpenAI Agents SDK, CrewAI, and Google ADK.
from intrupt_py_sdk.adapters.langgraph import ApprovalGraph, approval_required
from langchain_core.tools import tool
@tool
@approval_required(
action="transfer_funds",
channel="slack",
args=["account", "amount"],
)
def transfer_funds(account: str, amount: float):
"""Transfer funds to an account."""
bank.transfer(account, amount)Every one of these was about to run — autonomously. Without a gate, most agent frameworks would have executed all of them.
kubectl delete namespace productionInfra agent · cleanup taskterraform destroy -auto-approveIaC agent · reconcile driftDROP DATABASE users;SQL agent · schema migrationgit push --force origin mainRelease agent · hotfixaws iam delete-role prod-adminCloud agent · resource sweepDELETE FROM orders; -- no WHERESupport agent · bulk fixPolicies decide what needs a human. Everything else runs untouched.
Aegmis isn't just a Slack button. It sits between your agent and the world: every high-stakes tool call runs through your policies before it executes — allowed, held for a human, or blocked — and every decision is recorded.
Approvals, a policy engine, runtime interception, and a full audit trail — one governance layer across LangGraph, OpenAI Agents SDK, CrewAI, and Google ADK.
From a two-line integration to enterprise-grade audit logs.
Route by tool, action, amount, or any condition. The right human gets asked — not everyone, not no one.
Approvers see the full context and click once. No new dashboard to learn, no context switching.
Approved? The agent picks up exactly where it stopped. Rejected? A clean error the agent can handle gracefully.
LangGraph, Google ADK, OpenAI Agents SDK, CrewAI, or plain Python. One decorator and a wrapper — nothing else changes.
Every decision is logged — who approved, when, and what the agent was about to do. Ready for compliance reviews.
Admins own policies and users. Contributors scope approvals to their own agents. No one sees more than they should.
Stack @approval_required on any tool. The agent pauses before executing — nothing runs until a human says so.
@tool
@approval_required(action="purchase_stock", message="Approve buying shares", channel="slack", args=["symbol", "quantity", "amount"])
def buy_stock(symbol: str, quantity: int, amount: float):
...An interactive Slack message lands with the full context — tool name, arguments, who triggered it. One click to decide.
Approval required: buy_stock
ticker: AAPL qty: 10
[Approve] [Reject]Approved actions resume instantly. Rejected actions return a clean error the agent handles. Either way, it's on the record.
✓ Approved by [email protected]
Agent resumed in 47s
Audit log: approval_id_...LangGraph, Google ADK, OpenAI Agents SDK, or CrewAI. Four changes to your existing agent — no rewrites.
Stack @approval_required under @tool. No changes to the tool body.
@tool
@approval_required(
action="buy_stock",
message="Approve stock purchase",
channel="slack",
args=["symbol", "quantity"],
)
def buy_stock(symbol: str, quantity: int):
...Replace direct graph.invoke calls with ApprovalGraph. Your graph, checkpointer, and config are unchanged.
from intrupt_py_sdk.adapters.langgraph import ApprovalGraph
approval_graph = ApprovalGraph(
graph=graph,
callback_url="https://your-agent/resume",
callback_secret=os.getenv("AGENT_RESUME_SECRET", ""),
)
result = await approval_graph.ainvoke(input, thread_id=tid)Check the result status. When pending_approval, return a 202 — Slack handles the rest.
result = await approval_graph.ainvoke(input, thread_id=tid)
if result["status"] == "pending_approval":
return {"status": 202, "approval_id": result["approval_id"]}
# result["result"] has the full graph stateAegmis calls this after a human decides. It resumes the graph from the checkpoint — no polling needed.
@app.post("/resume")
async def resume(body: ResumeRequest):
result = await approval_graph.aresume(
thread_id=body.thread_id,
approved=body.approved,
approval_id=body.approval_id,
)
return result| Task | Time |
|---|---|
| Decorate tools | 2 min / tool |
| Wrap graph + add /resume endpoint | 30 min |
| Run Aegmis API + configure Slack app | 30–60 min |
| Total | ~1 hour |
Your graph, checkpointer, and thread IDs stay exactly as they are. Read the full SDK docs → Need help? Reach out →
Other supported frameworks
No @tool wrapper — ADK injects tool_context. Uses ApprovalRunner + session_id.
from intrupt_py_sdk.adapters.google_adk import (
approval_required, ApprovalRunner
)
@approval_required(action="buy_stock", ...)
async def buy_stock(symbol, qty, tool_context=None):
...
runner = ApprovalRunner(agent=agent, ...)
result = await runner.run(session_id, message)
result = await runner.resume(session_id, approved=True, ...)Decorator goes inside @function_tool. Uses ApprovalAgentRunner + thread_id.
from intrupt_py_sdk.adapters.openai_agents import (
approval_required, ApprovalAgentRunner
)
@function_tool
@approval_required(action="buy_stock", ...)
async def buy_stock(symbol, qty): ...
runner = ApprovalAgentRunner(agent=agent, ...)
result = await runner.run(thread_id, message)
result = await runner.resume(thread_id, approved=True, ...)Factory function wraps a BaseTool instance. Uses ApprovalCrew + run_id.
from intrupt_py_sdk.adapters.crewai import (
approval_required, ApprovalCrew
)
gated = approval_required(
MyTool(), action="buy_stock", ...
)
crew = ApprovalCrew(crew=Crew(...), ...)
result = await crew.kickoff(run_id, inputs={})
result = await crew.resume(run_id, approved=True, ...)Approve or reject with a single click, right inside existing channels.
"Our trading agent was ready for months. We just didn't trust it. Aegmis solved that — every order above a threshold asks first. We shipped in a week."
"Our ops team lives in Slack, not dashboards. Aegmis meets them there — approve or reject in one click, right where they already are. Zero training required."
"We had a LangGraph agent ready for two months. Legal kept blocking it. Added Aegmis in an afternoon — every risky action now has a paper trail. Shipped the next day."
No credit card to get started. Upgrade when you need more approvals, users, or channels.
Try it on your own agent. No credit card needed.
For teams who need to ship and stay in control.
For orgs where every decision needs a paper trail.
Two lines of code. One hour of setup. AI agents you can put in production without losing sleep.