agentapprovalprotocol 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.5
2
+ Name: agentapprovalprotocol
3
+ Version: 0.1.0
4
+ Summary: Put an AI agent's tool calls behind an Agent Approval Protocol (AAP) approval provider.
5
+ Project-URL: Homepage, https://agentapprovalprotocol.io
6
+ Project-URL: Source, https://github.com/agentapprovalprotocol/agentapprovalprotocol
7
+ License-Expression: Apache-2.0
8
+ Keywords: aap,agents,ai,approval,human-in-the-loop
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Typing :: Typed
11
+ Requires-Python: >=3.10
12
+ Requires-Dist: httpx>=0.27
13
+ Provides-Extra: langgraph
14
+ Requires-Dist: langchain>=1.0; extra == 'langgraph'
15
+ Requires-Dist: langgraph>=1.0; extra == 'langgraph'
16
+ Provides-Extra: pydantic-ai
17
+ Requires-Dist: pydantic-ai-slim>=2.55; (python_full_version >= '3.11') and extra == 'pydantic-ai'
18
+ Description-Content-Type: text/markdown
19
+
20
+ # Agent Approval Protocol for Python
21
+
22
+ Put an AI agent's tool calls behind an [AAP](https://agentapprovalprotocol.io) approval provider. Each call waits for the provider's decision, runs only if approved, and runs at most once.
23
+
24
+ ```sh
25
+ pip install agentapprovalprotocol
26
+ ```
27
+
28
+ ## Check a tool call
29
+
30
+ ```python
31
+ from agentapprovalprotocol import Call, Client, Gate
32
+
33
+ gate = Gate(Client("https://approvals.example.com/api/aap", token))
34
+
35
+ with gate.guard(Call(key=f"{run_id}:{tool_call.id}", tool=tool_call.name, arguments=tool_call.args)) as verdict:
36
+ if verdict:
37
+ result = run_tool(tool_call)
38
+ else:
39
+ result = verdict.reason # return this to the model as the tool result
40
+ ```
41
+
42
+ `key` must identify the tool call within its run, and stay the same if the call is seen again after a retry or resume. `guard` reports whether the tool succeeded when the block exits.
43
+
44
+ `AsyncGate` and `AsyncClient` provide the same API for `asyncio`.
45
+
46
+ ## Pause instead of waiting
47
+
48
+ With `mode="async"`, `check` returns `Pending` when there is no decision yet, so the run can pause and the process can exit. Mount a `Receiver` where the provider can reach it. When a decision arrives it wakes the run, and the gate checks the decision again before anything runs.
49
+
50
+ Framework integrations handle pausing and resuming for you.
51
+
52
+ ## LangChain, LangGraph and Deep Agents
53
+
54
+ ```sh
55
+ pip install "agentapprovalprotocol[langgraph]"
56
+ ```
57
+
58
+ ```python
59
+ from agentapprovalprotocol.langgraph import ApprovalMiddleware
60
+
61
+ approvals = ApprovalMiddleware("https://approvals.example.com/api/aap", token)
62
+ agent = create_agent(model, tools=tools, middleware=[approvals])
63
+ ```
64
+
65
+ Every tool call the agent makes goes to the provider. A denied call returns the reason to the model as the tool result.
66
+
67
+ For Deep Agents, also add the middleware to every subagent:
68
+
69
+ ```python
70
+ from agentapprovalprotocol.langgraph import deep_agent_subagents
71
+
72
+ agent = create_deep_agent(model, tools=tools, middleware=[approvals], subagents=deep_agent_subagents(approvals, my_subagents))
73
+ ```
74
+
75
+ To pause instead of waiting, use `ApprovalMiddleware(..., mode="async")` with a checkpointer, and mount a `Receiver` with `resumers={"langgraph": resumer(agent)}`. On LangSmith Deployment, use `deployment_resumer(get_client())` in a custom route instead. Resuming a thread any other way cannot approve a call: the middleware asks the provider again.
76
+
77
+ ## Pydantic AI
78
+
79
+ ```sh
80
+ pip install "agentapprovalprotocol[pydantic-ai]"
81
+ ```
82
+
83
+ Needs Python 3.11 or later.
84
+
85
+ ```python
86
+ from agentapprovalprotocol.pydantic_ai import ApprovalCapability
87
+
88
+ approvals = ApprovalCapability("https://approvals.example.com/api/aap", token)
89
+ agent = Agent(model, tools=tools, capabilities=[approvals])
90
+ ```
91
+
92
+ Every tool call the agent makes goes to the provider, including MCP and other toolset tools. A denied call returns the reason to the model as a failed tool result. Add the same capability to every agent you run as a sub-agent.
93
+
94
+ Tools that run at the model provider, such as native web search or code execution, cannot be sent for approval. A run that includes one stops with an error. Use a local tool instead.
95
+
96
+ To pause instead of waiting, use `ApprovalCapability(..., mode="async")` and add `DeferredToolRequests` to the agent's `output_type`. When a run ends with `DeferredToolRequests`, save `result.conversation`. Mount a `Receiver` with `resumers={"pydantic-ai": resumer(agent, load=load, save=save)}`, where `load(conversation_id)` returns the saved conversation and `save(conversation)` stores the resumed one. Calls inside a sub-agent wait instead of pausing. Continuing a conversation any other way cannot approve a call: the capability asks the provider again, and an approval with edited arguments is refused.
@@ -0,0 +1,12 @@
1
+ agentapprovalprotocol/__init__.py,sha256=KZtGV2iXUopQNR2KVXZkMbcwKl_1_MJhULEQAOdP6fk,829
2
+ agentapprovalprotocol/_client.py,sha256=M8AydlTKouS2ILT_QS5hi0ZMTp3EdugR-R48SgP7iPw,8388
3
+ agentapprovalprotocol/_gate.py,sha256=rSD502lzXmRxF71NR7aMssA_I0p8NuEMlCMv3OV3Mt8,13345
4
+ agentapprovalprotocol/_wire.py,sha256=dVtshyzB5zzQjF3gbR3ZZomPJoIIAtNNNcRAR8a32ig,8505
5
+ agentapprovalprotocol/langgraph.py,sha256=jjxDGkOFTfrsi0qpiZ5DIPA6PkKt_OT7elVmoHhEa9g,10912
6
+ agentapprovalprotocol/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ agentapprovalprotocol/pydantic_ai.py,sha256=2V_fSYW--n5yjdKopk9hYku420LEG7_eUCAb3RQx1h0,10906
8
+ agentapprovalprotocol/receiver.py,sha256=NUMpnY6QZm0RcOQysBWWE9-zZGQRrDdkr-ltiGB--tg,7186
9
+ agentapprovalprotocol/testing.py,sha256=aBY4Xi0w1nW2UEVMIK8v7lcAFnLF1tiFMFEymq1NbK0,7931
10
+ agentapprovalprotocol-0.1.0.dist-info/METADATA,sha256=KNo9IXxccvwwXH8gmC5wnxHtPJ0zIn5Qd2QCjB5XVNI,4529
11
+ agentapprovalprotocol-0.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
12
+ agentapprovalprotocol-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.4
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any