Human-in-the-loop
RoadmapThis capability is on the Roadmap; the API shown here is the planned design.
Refunds over €100 need a human. Today that is bespoke code, per team, per framework. DDK will let you declare the approval requirement on the tool itself:
@donkey.tool(approval="required", risk="financial")
async def issue_refund(ticket_id: str, amount: float): ...When the agent calls issue_refund, DDK raises ApprovalRequired (or triggers
the framework’s own interrupt), records the pending approval against the
correlation ID, and resumes when you resolve it:
await donkey.approvals.resolve(approval_id, approved_by=reviewer.id)Mapped onto what your framework already has
DDK does not introduce a new pause mechanism. It maps one vocabulary onto the primitive each framework already ships:
| Framework / protocol | Native primitive |
|---|---|
| LangGraph | interrupt() / Command(resume=…) |
| OpenAI Agents SDK | tool-approval / guardrail hooks |
| Google ADK | before/after tool callbacks |
| Strands | hooks |
| MCP | elicitation |
| Omni Gateway | Trusted Agent Identity step-up (MFA) |
What DDK adds
Every framework already has human-in-the-loop. DDK adds three things on top, none of which is a new mechanism:
- Normalisation — one vocabulary across frameworks, so approval policy is not rewritten when a team switches from ADK to LangGraph.
- Auditability — the pending approval appears in the span, and the approver’s identity lands in the audit trail next to the correlation ID. “Who approved this refund?” becomes a query.
- Gateway routing — a high-risk approval can be routed through the gateway’s identity layer for step-up MFA, rather than trusting a click in your own UI.
Out of scope
DDK will not ship an approval queue or an approval UI — both are on the will-not-build list. It integrates with whatever you already run: Slack, ServiceNow, or LangGraph’s own checkpointer.
A queue would mean owning a durable store, an escalation model, and a notification system — a product rather than a feature.