The control layer for AI agents. Check any agent action before it runs: allow, stop, or escalate.
Project description
Checkpoint Python SDK
The control layer for AI agents. Check any agent action before it runs, evaluate it against your policy, and decide: allow, stop, or escalate. Every decision is written to a tamper-evident audit log.
Install
pip install checkpoint-sdk
Quickstart
import checkpoint as cp
from checkpoint import Policy, rule, CheckpointStopped
cp.set_policy(Policy([
rule("transfer_funds", when="amount > 25000", verdict="escalate", to="cfo"),
rule("export_records", when="pii_rows > 10000", verdict="stop"),
]))
def process_payment(amount, recipient):
cp.check("transfer_funds", {"amount": amount, "recipient": recipient})
transfer_funds(amount, recipient) # only reached if allowed
If the amount is within policy, the check returns and the transfer runs. If it crosses a threshold, the check stops it (raising CheckpointStopped) or escalates to a human.
Reading the verdict
verdict = cp.check("transfer_funds", {"amount": amount}, raise_on_stop=False)
if verdict.allowed:
transfer_funds(amount, recipient)
else:
print(verdict.reason)
The three verdicts
- allow: within bounds, proceeds instantly.
- stop: crosses a hard limit, execution stops.
- escalate: needs a human, routes to the right person and waits.
Audit log
for entry in cp.audit_log.entries():
print(entry["log_id"], entry["verdict"], entry["action"])
assert cp.audit_log.verify() # hash chain intact
Framework integrations
Gate your agent's tools so cp.check() fires automatically before each one runs. A stopped action raises CheckpointStopped and the tool never executes; an escalation returns the verdict without running.
Any tool or function, with the @guard decorator:
from checkpoint.integrations import guard
@guard("transfer_funds")
def transfer_funds(amount, to):
...
transfer_funds(amount=80000, to="acct_1") # checked before it runs
Positional or keyword arguments are mapped to the payload by parameter name, so a rule on amount works either way. Shape the payload yourself with payload_from if your rules read different fields.
LangChain:
from checkpoint.integrations import wrap_langchain_tool
guarded = wrap_langchain_tool(my_tool, action="transfer_funds")
# give `guarded` to your agent instead of the raw tool
CrewAI:
from checkpoint.integrations import wrap_crewai_tool
guarded = wrap_crewai_tool(my_tool, action="transfer_funds")
AutoGen:
from checkpoint.integrations import register_autogen
register_autogen(transfer_funds, action="transfer_funds",
agent=assistant, executor=user_proxy, name="transfer_funds")
The SDK has no hard dependency on any framework; each is imported only when you call its wrapper.
Direct LLM tool calls (OpenAI, Anthropic, Gemini)
If you call a model directly instead of through an agent framework, the model proposes tool calls and your code runs them. Checkpoint checks each proposed call before you execute it.
from checkpoint.llm import check_openai_tool_calls
resp = client.chat.completions.create(model="gpt-4", messages=msgs, tools=tools)
for c in check_openai_tool_calls(resp):
if c.allowed:
result = run_tool(c.name, c.args)
else:
result = c.verdict.reason # stopped or escalated; tool not run
# feed result back to the model as the tool result for c.id
Same shape for the other providers:
from checkpoint.llm import check_anthropic_tool_calls, check_gemini_function_calls
for c in check_anthropic_tool_calls(message): ...
for c in check_gemini_function_calls(response): ...
Each returns a CheckedCall per proposed call, with .allowed, .stopped, .escalated, the parsed .args, the provider's call .id (for returning results), and the full .verdict. Nothing executes automatically; you run the allowed calls and stay in control of the loop.
Use name_map={"wire_money": "transfer_funds"} if the model's function name differs from your policy action, and payload_from=... to reshape arguments into the fields your rules read.
Run the example and tests
PYTHONPATH=. python examples/payment_agent.py
pip install -e ".[dev]" && pytest
Hosted mode
By default the SDK runs a local in-memory engine, so you can use it without an account. To evaluate against your team's shared policy and durable audit log, point it at the hosted service:
cp.configure(api_key="cp_live_xxx", base_url="https://your-checkpoint-host")
With base_url set, check() calls POST /v1/check on the server. If the service is unreachable it fails closed (stops the action) by default. The public API is identical in both modes.
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file checkpoint_protocol-0.1.0.tar.gz.
File metadata
- Download URL: checkpoint_protocol-0.1.0.tar.gz
- Upload date:
- Size: 16.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e8143341a6b491d01f45ce3351f15ee45062fbfa8fcb467c16b7e2b253378ca
|
|
| MD5 |
51714f7b95a0bc7542a99838d84ed3eb
|
|
| BLAKE2b-256 |
bfcf52fd5195c291b7da2b5858c4b9f61f95c83d40897b642b100ac7ebfe686f
|
File details
Details for the file checkpoint_protocol-0.1.0-py3-none-any.whl.
File metadata
- Download URL: checkpoint_protocol-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52886d16c8824d87e6f583b794a645e0904cdd88f3d241d47a251e23ab18bd7b
|
|
| MD5 |
9066efc3569853e06c35f702ed056a3c
|
|
| BLAKE2b-256 |
c2a1f37fd98956bfa3492b0e3a811f87a67bda2d23f35b341925e26e1a64de55
|