Causalor
Runtime governance for AI agents. Two layers of one control:
- Block.
pre_commit()checks a proposed action against typed constraints and refuses it before it executes, returning a proof of why. Runs in your process. No network call, no model call, no account. - Correct.
track_action()reports what the agent did, andinject()returns a correction for its next turn when it has moved off policy, so the out-of-policy action is often never proposed. You do not diagnose the drift or write the fix.
pip install causalor
The published package is causalor. causalor-sdk is an internal development
package and is not the one to install.
Block an action, without an account
This runs offline. No API key, no signup, nothing reaches a server.
from causalor import Causalor, AgentStateSchema, FormalConstraint
schema = AgentStateSchema(version="1.0.0")
schema.register_field("refund_amt", "number")
c = Causalor(agent_id="refund-agent")
c.set_state_schema(schema)
c.register_constraints([FormalConstraint(
constraint_id="refund_ceiling", variable="refund_amt",
operator="<=", threshold=500, scope="SAFETY_CONSTRAINT",
)], replace=True)
# the agent decides to refund 900 against a 500 ceiling
result = c.pre_commit("customer-42", "issue_refund", state={"refund_amt": 900})
print(result.allowed) # False
print(result.proofs[0].proof_string) # refund_amt=900 <= 500 -> False
print(result.state_snapshot_hash)
print(result.proofs[0].proof_fingerprint)
Output:
False
refund_amt=900 <= 500 -> False
sha256:v1:766ccc520ddeb830efe963d4b45434ab38e58dfd2ce41ffb28e59ad86d1e8586
sha256:v1:eb2c6c2242180923744ba837d376e58601bb02efeeebf60b57dc7aed754ba608
Those two hashes are not examples. Run the snippet and you will get the same values, on your machine, today or in a year, because the verdict is computed from the state and the rule rather than inferred by a model. If you get something else, that is a bug worth reporting.
(evaluated_at is a wall-clock timestamp and does change. The hashes do not.)
Correct drift while the agent is still reasoning
Correction needs the control plane, so three environment variables and nothing else:
CAUSALOR_API_KEY=cal_... # shown once on first login
CAUSALOR_API_URL=https://gw.causalorlabs.com
CAUSALOR_POLICY_ID=your-policy # the policy you activated in the console
c = Causalor(agent_id="refund-agent") # key, URL and telemetry read from env
c.load_policy_constraints_from_env() # pull the guardrails you activated
c.track_action("customer-42", agent_action) # session id first
correction = c.inject("customer-42") # "" when nothing is wrong
if correction:
prompt += correction
You can also start with nothing enforced: point a live agent at Causalor with no limits set and it reports where the agent drifted and which limits it would have crossed, on your real traffic, before you turn anything on.
API
| Method | Purpose |
|---|---|
Causalor(agent_id=, api_url=, api_key=, tenant_id=) |
Key and URL fall back to the environment |
set_state_schema(schema) |
Declare the fields rules may reference |
register_constraints(constraints, replace=False) |
Register rules locally |
load_policy_constraints_from_env(required=None) |
Pull the activated policy instead |
pre_commit(user_id, action_name, state=) |
Check before the action runs |
track_action(user_id, action_content) |
Report what the agent did |
inject(user_id) |
Get a correction for the next turn |
register_agent(agent_id, system_prompt, tools=) |
Report an off-path agent |
pre_commit returns allowed, status, proofs, evaluated_constraints and
state_snapshot_hash.
Three things that cause most integration bugs
track_action(user_id, action_content)takes the session id first. Passing the action text first silently breaks drift detection rather than erroring.- Do not configure OpenTelemetry. The SDK installs its own exporter from
CAUSALOR_API_URL, and leaves an existing tracer provider alone if it finds one. SetCAUSALOR_AUTO_OTEL=falseto opt out. - Do not call
register(). Useregister_agent(...).
Deployment routes
The same engine behind all three, so you can move between them without re-authoring anything:
- In-process SDK, this package. Nothing in your model path.
- Sidecar, one container in your VPC, so model traffic never leaves it.
- Hosted gateway, point an OpenAI or Anthropic client
base_urlathttps://gw.causalorlabs.com/v1.
Links
- Quickstart: https://causalorlabs.com/quickstart
- Plain-markdown quickstart for coding agents: https://causalorlabs.com/quickstart.md
- Pricing: https://causalorlabs.com/pricing
Blocking is free permanently, on every plan.
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 causalor-0.2.2.tar.gz.
File metadata
- Download URL: causalor-0.2.2.tar.gz
- Upload date:
- Size: 62.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46baa1c4099df1d0f78ad17bd7c2cb70c027c41399e59b22421e097a6ef2dcaa
|
|
| MD5 |
79831aa3f3f7e4e9c393f349698c080c
|
|
| BLAKE2b-256 |
0dd7254ebc2b58c05da5e817880b3f65e4679968a497bb43df18f93f2ca55ebb
|
File details
Details for the file causalor-0.2.2-py3-none-any.whl.
File metadata
- Download URL: causalor-0.2.2-py3-none-any.whl
- Upload date:
- Size: 63.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed37f6caa3ea48c34725a3ba00932993ac988b760f8950c3cdc866c5aab6a7d7
|
|
| MD5 |
3e7be18742ec05d797bc1362feda3807
|
|
| BLAKE2b-256 |
dae4209b5b381c81dcfe66eeaeabea1c61ff943ead3a68d6805ddd25fd1490bc
|