Skip to main content

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:

  1. Capture — every OpenAI / Anthropic / LiteLLM / LangChain call is auto-recorded (model, tokens, cost, latency).
  2. Approve — high-stakes calls pause until a human signs off in the FORMAAI inbox.
  3. Kill — halt any agent from the dashboard with no redeploy.
  4. Prove — every captured run is HMAC-signed and tamper-evident.

License: MIT Python 3.8+


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) returns True → the call pauses until a human decides in the FORMAAI inbox (fail-closed).
  • Kill: kill_switch=True → triggering a kill from the dashboard raises KillSwitchTriggered on 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

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

forma_sdk-3.3.0.tar.gz (54.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

forma_sdk-3.3.0-py3-none-any.whl (54.1 kB view details)

Uploaded Python 3

File details

Details for the file forma_sdk-3.3.0.tar.gz.

File metadata

  • Download URL: forma_sdk-3.3.0.tar.gz
  • Upload date:
  • Size: 54.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for forma_sdk-3.3.0.tar.gz
Algorithm Hash digest
SHA256 44133b0a0007c94a1d421accdf6472998ac15979447a58fde08c8a3245245926
MD5 a1cf4dfddd77dad61a0e13e30a127895
BLAKE2b-256 f5489fdd58388e08a8eae73f47635f5b1f8cb0c3b7ffc34229ac3e4047b8f017

See more details on using hashes here.

File details

Details for the file forma_sdk-3.3.0-py3-none-any.whl.

File metadata

  • Download URL: forma_sdk-3.3.0-py3-none-any.whl
  • Upload date:
  • Size: 54.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for forma_sdk-3.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ccb3b9c3ec490a279ba6d346a63117366d90a46e2234b3e16d85f921a70707a2
MD5 1272cbef0689830c5e0b27fb1fcca13d
BLAKE2b-256 2312d4fff82434c88271ba2f82ed5e604705ba444ee124ec4e58cac5c23e48ea

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page