FORMAAI — the AI Agent Firewall. Zero-config capture of every LLM call, human approvals, kill switch, and a cryptographically signed audit trail.
Project description
FORMAAI SDK — v3.0.0
The AI Agent Firewall. Capture every LLM call, pause high-stakes ones for a human, halt any agent instantly, and prove it all with a signed audit trail.
FORMAAI sits between your code and the model. The moment you call tl.init(), every LLM and tool call is captured as a cryptographically signed run, can be paused for human approval, and can be killed from the dashboard in under two seconds. Four pillars, zero policy config:
- Capture — every OpenAI / Anthropic / LiteLLM / LangChain call is auto-recorded (model, tokens, cost, latency).
- Approve — high-stakes calls pause until a human signs off in the FORMAAI inbox.
- Kill — halt any agent from the dashboard with no redeploy.
- Prove — every captured run is HMAC-signed and tamper-evident.
Install
pip install forma-sdk
Import name is trustlayer:
import trustlayer as tl
Quickstart — one line, everything captured
import trustlayer as tl
# One call. Every LLM call in your process is now captured + signed.
# No decorators, no context managers, no edits inside your business logic.
tl.init(api_key="tl_live_YOUR_KEY") # from formaai.in → Settings
# Your existing code is unchanged.
result = run_underwriting_model(application)
Confirm it's connected:
print(tl.verify())
# → {"verified": True, "capture": "active", "signing": "enabled",
# "kill_switch": "off", "approvals": "off", ...}
The four pillars
import trustlayer as tl
tl.init(
api_key="tl_live_YOUR_KEY",
human_sponsor="ops@company.com", # accountable human on every run
kill_switch=True, # halt this agent from the dashboard
max_cost_usd=5.0, # hard per-run cost cap
require_approval_when=lambda ctx: ctx.get("amount", 0) > 1_000_000,
approval_message="High-value transaction requires human review.",
)
- Capture is on by default — nothing else needed.
- Approve:
require_approval_when(ctx)returnsTrue→ the call pauses until a human decides in the FORMAAI inbox (fail-closed). - Kill:
kill_switch=True→ triggering a kill from the dashboard raisesKillSwitchTriggeredon the next call in < 100 ms. - Prove: every run is signed with your API key; verify with
trustlayer verify <run_id>.
Multiple agents — tl.register() / agents= (zero edits)
Map your existing functions to agents without touching their bodies. Each one gets its own discrete, signed run and its own approval / kill / cost config:
import trustlayer as tl
from my_app import approve_loan, validate_kyc, detect_fraud
tl.init(
api_key="tl_live_YOUR_KEY",
agents={
"kyc-validator": validate_kyc, # bare callable
"loan-approval": {"fn": approve_loan, "risk_level": "HIGH", "kill_switch": True},
"fraud-detector": {"fn": detect_fraud,
"require_approval_when": lambda ctx: True},
},
)
# Or register after init (decorator form also works):
tl.register("loan-approval", approve_loan, risk_level="HIGH", max_cost_usd=2.0)
@tl.register("kyc-validator", kill_switch=True)
def validate_kyc(doc): ... # one line above the def — body unchanged
# Call them exactly as before — each captured and attributed independently.
result = approve_loan(application)
Per-agent kwargs (same as tl.init's per-agent set): compliance, risk_level, human_sponsor, purpose, max_cost_usd, require_approval_when, approval_message, approval_title, approval_timeout, approval_poll_interval, approval_via, version, kill_switch. Unknown keyword → TypeError.
Human approvals (human-in-the-loop)
tl.init(
api_key="tl_live_YOUR_KEY",
require_approval_when=lambda ctx: ctx.get("amount", 0) > 1_000_000,
approval_message="High-value transaction requires human review.",
)
result = approve_loan(application) # pauses for sign-off on high-stakes calls (fail-closed)
require_approval_when(ctx) receives {agent_name, provider, model, action_type, prompt, tool_name, tool_args}; return True to require approval. It may also return a dict for per-call overrides: {"required": True, "timeout": 60, "message": "STAT review"}. Predicate errors fail closed (require approval).
from trustlayer import ApprovalRejectedError, ApprovalTimeoutError
try:
result = approve_loan(application)
except ApprovalRejectedError as e:
... # a human rejected the action — it was NOT executed
except ApprovalTimeoutError as e:
... # no decision within the timeout
Kill switch
tl.init(api_key="tl_live_YOUR_KEY", kill_switch=True) # process-wide
# or per agent:
tl.register("fraud-agent", detect_fraud, kill_switch=True)
When you trigger a kill from the dashboard, the next LLM/tool call raises KillSwitchTriggered — no redeployment. Works offline too via FORMA_KILL_SWITCH=1 or a ~/.forma/kill.lock file (useful in air-gapped / strict-egress Kubernetes).
Signed audit trail (Prove)
Every captured run is finalized, HMAC-signed with your API key, and shipped to your audit trail. Verify any run's signature locally — no API key needed if you use an Ed25519 keypair:
trustlayer verify <run_id> # ✓ VERIFIED — signature is valid and untampered
trustlayer export <run_id> # download the signed record (PDF)
trustlayer keygen # generate an Ed25519 signing keypair
Observability API
| Call | Returns |
|---|---|
tl.verify() |
{verified, agent, capture, signing, kill_switch, approvals, summary} — confirm the SDK is connected and capturing. |
tl.status() |
{version, capture_active, ambient_runs, kill_switch_armed, kill_switch_active, approvals_configured, ambient_agent, frameworks}. |
tl.init(api_key="tl_live_...", kill_switch=True,
require_approval_when=lambda ctx: True)
tl.verify()
# → {"verified": True, "capture": "active", "signing": "enabled",
# "kill_switch": "armed", "approvals": "configured", ...}
tl.init() parameters
| Parameter | Description |
|---|---|
api_key |
FORMAAI API key (or FORMA_API_KEY env, or forma setup). |
api_url |
Backend URL override (default https://api.formaai.in). |
agent_name |
Display name for ambient auto-captured runs. |
human_sponsor |
Accountable human recorded on every run. |
auto_capture (True) |
Auto-patch OpenAI/Anthropic/LiteLLM/LangChain. |
ambient_runs (True) |
Create signed runs for auto-captured calls. |
kill_switch (False) |
Start a process-level kill-switch watcher. |
compliance |
Optional framework tags recorded on runs (metadata only). |
agents |
Zero-edit multi-agent map. {"name": fn} or {"name": {"fn": fn, ...}}. |
purpose / risk_level |
Metadata recorded on runs. |
max_cost_usd |
Hard per-run cost cap; runs over it are marked failed. |
require_approval_when |
Predicate ctx -> bool — pause for a human when it returns True. |
approval_message / approval_title / approval_timeout / approval_poll_interval / approval_via |
Approval configuration. |
timeout (10) / max_retries (2) |
HTTP transport settings. |
CLI
trustlayer setup # one-time guided setup (paste your key)
trustlayer scan app.py # check a file for governance coverage
trustlayer verify <run_id> # verify a run signature
trustlayer export <run_id> # download a signed record
trustlayer status # API connection + fleet overview
trustlayer keygen # Ed25519 signing keypair
Node.js / TypeScript
Coming soon. Capture, approvals, kill switch, and signing are Python-first today.
Dashboard & docs
- Dashboard: formaai.in
- Developer guide: formaai.in/developer-guide
Migrating from 2.x
company_policy={} and the local PII / prompt-injection gate (enforce, preset,
block, allow, pii, authorized_actions, domain, tl.preview,
ComplianceViolation) were removed in 3.0.0. FORMAAI is now a pure
capture + approve + kill + prove firewall — you define what needs a human and
what can be killed; we capture and sign everything. Remove company_policy
from your tl.init() and keep require_approval_when / kill_switch /
max_cost_usd as top-level params.
License
MIT — see LICENSE.
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 forma_sdk-3.3.1.tar.gz.
File metadata
- Download URL: forma_sdk-3.3.1.tar.gz
- Upload date:
- Size: 67.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e97f9a7f02993ff5b2962708dc299f1e60b7b0dd0a6354e69bc941ecbf09541
|
|
| MD5 |
44236bd4a552cf6c3e362440ea220804
|
|
| BLAKE2b-256 |
79fa5d2907b938d2c9ec6773fcd1160869e6b28633985e8cc78b7b9e65d88fc3
|
File details
Details for the file forma_sdk-3.3.1-py3-none-any.whl.
File metadata
- Download URL: forma_sdk-3.3.1-py3-none-any.whl
- Upload date:
- Size: 63.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe99a0e388056229717e42a82db82ef289c6faa6fb80c99797c8aea8fe7ed8e6
|
|
| MD5 |
ebf8b999993b0925a07e882820d63504
|
|
| BLAKE2b-256 |
dc1b5e40383a2eb1f9f8f4395cd4fa36fc4dc27b494ff780bb9982d290d64c95
|