Skip to main content

Guard LLM tool calls with rules, scoring, and audit trails.

Project description

cascade

Guard LLM tool calls with rules, scoring, and audit trails.

PyPI version Python License: MIT Tests

cascade is a lightweight governance layer for AI agent tool calls. It sits between your LLM and tool execution — evaluate every tool call against rules, rank survivors by strategy, and audit every decision.

Quick Start

from cascade import DecisionPipeline

pipe = DecisionPipeline()
result = pipe.guard(
    tool_calls=[
        {"id": "1", "name": "search", "confidence": 0.92},
        {"id": "2", "name": "delete", "confidence": 0.15},
    ],
    rules=[
        {"field": "confidence", "op": "gte", "value": 0.5},
        {"field": "name", "op": "nin", "value": ["delete"]},
    ],
    strategy="softmax",
    top_k=1,
)

if result["selected"]:
    safe = result["selected"][0]
    print(f"Safe: {safe['name']} ({safe['confidence']})")

Installation

pip install cascade

Zero external dependencies. Optional extras extend the feature set:

pip install cascade[openai]     # OpenAI SDK adapter
pip install cascade[anthropic]  # Anthropic SDK adapter
pip install cascade[langchain]  # LangChain adapter
pip install cascade[crewai]     # CrewAI adapter
pip install cascade[gemini]     # Gemini SDK adapter
pip install cascade[autogen]    # AutoGen adapter
pip install cascade[yaml]       # YAML policy files + cascade policy lint

Adapters

Framework-specific adapters let you plug cascade governance into your existing agent code with minimal changes. Each adapter is a thin (<80 lines) layer — zero impact on the core codebase.

# OpenAI — auto-govern every chat.completions.create
from openai import OpenAI
from cascade import DecisionPipeline
from cascade.adapters.openai import wrap_openai_client

client = wrap_openai_client(
    OpenAI(),
    pipeline=DecisionPipeline(),
    rules=[{"field": "name", "op": "nin", "value": ["delete_file", "exec"]}],
)
# LangChain — post-process agent output
from cascade.adapters.langchain import guard_agent_output

result = agent.invoke({"input": "search for papers on AI safety"})
result = guard_agent_output(result, pipeline=pipe, rules=[...])

Why cascade?

  • Zero dependencies — pure Python, no pip wars
  • Plugs into any LLM framework — OpenAI, LangChain, or custom
  • Audit built in — every guard() auto-writes JSONL audit trails
  • 5 selection strategies — softmax / linear / uniform / threshold / ucb1
  • Self-emergence — C₃↔C₄ closed loop learns from outcomes
  • Composite rulesall_of / any_of / not_ for complex policies
  • Actionsblock / redirect / transform for automated remediation

Policies

Define governance rules in YAML for repeatable, audit-friendly policies.

# policy.yaml
name: strict-tools
description: Block dangerous tools
rules:
  - field: name
    op: nin
    value: [delete_file, exec, rm]
  - field: confidence
    op: gte
    value: 0.7
  - all_of:
      - field: name
        op: eq
        value: code_interpreter
      - field: confidence
        op: gte
        value: 0.9

strategy: softmax
top_k: 1
cascade policy lint policy.yaml
cascade check --tool-calls @tools.json --policy policy.yaml

Composite rules (all_of / any_of / not_), @import directives, and full schema validation are supported.

Audit chain integrity

Every guard() decision is recorded in a SHA-256 hash-chained JSONL audit trail. Each entry links to its predecessor via prev_hash, making the log tamper-evident.

cascade audit verify
from cascade._audit import AuditTrail

trail = AuditTrail()
result = trail.verify()  # {'valid': True, 'entries': 42, ...}

C1–C4 Architecture

C1 (Gate)      : Rule engine — 11 operators + AND/OR/NOT composition
C2 (Trigger)   : Event triggers — condition callbacks + state machine
C3 (Selector)  : Selection pressure — uniform/linear/softmax/threshold ranking
C4 (Feedback)  : Feedback loop — binary/proportional/threshold reward
Linkage        : C₃↔C₄ closed loop — rewards adjust future selection

Docs

File What it covers
docs/usage.md guard() API, DecisionPipeline, AuditTrail
docs/rules.md Leaf rules, rule presets, composite rules (all_of/any_of/not_)
docs/strategies.md Selection strategies and when to use each
docs/cli.md cascade check / policy lint / audit verify CLI reference
docs/owasp.md OWASP Agentic Top 10 compliance mapping
CHANGELOG.md Version history

Integrations

Framework Adapter Lines Install
OpenAI SDK wrap_openai_client() / guard_openai_response() ~70 cascade[openai]
Anthropic SDK guard_anthropic_response() / wrap_anthropic_client() ~70 cascade[anthropic]
LangChain guard_agent_output() ~55 cascade[langchain]
CrewAI guard_crew_output() / wrap_crew() ~65 cascade[crewai]
Gemini SDK guard_gemini_response() / wrap_genai_client() ~80 cascade[gemini]
AutoGen guard_agent_reply() / wrap_agent() ~120 cascade[autogen]
MCP Server guarded_tool() / MCPServerGuard ~100 zero-dep (core)

Each adapter is opt-in — the core stays zero-dependency. All adapters live in src/cascade/adapters/ and import only what they need at runtime.

For custom framework integrations, use pipe.guard() directly:

response = client.chat.completions.create(..., tools=my_tools)
result = pipe.guard(
    tool_calls=[{"id": t.id, "name": t.function.name, ...}],
    rules=[{"field": "name", "op": "nin", "value": BLOCKED_TOOLS}],
)

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

agent_armour-0.8.0.tar.gz (53.2 kB view details)

Uploaded Source

Built Distribution

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

agent_armour-0.8.0-py3-none-any.whl (49.1 kB view details)

Uploaded Python 3

File details

Details for the file agent_armour-0.8.0.tar.gz.

File metadata

  • Download URL: agent_armour-0.8.0.tar.gz
  • Upload date:
  • Size: 53.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for agent_armour-0.8.0.tar.gz
Algorithm Hash digest
SHA256 15bd288848ac17c54b4df70b75067720dc98bccfa66158f27326dac20b370007
MD5 f580c89147ab6aa3fe8c087720081f90
BLAKE2b-256 455b5dd8d014ae5ccb5a3a8d544c3ce1da1a044c9109091428a550d8229ee7ab

See more details on using hashes here.

File details

Details for the file agent_armour-0.8.0-py3-none-any.whl.

File metadata

  • Download URL: agent_armour-0.8.0-py3-none-any.whl
  • Upload date:
  • Size: 49.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for agent_armour-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 09a001e513924d709a502b99f12c8a55acfcf7940f68b9c08d63b6cc80bbddbe
MD5 852e93b2d55ed789300cf72b8eda9c6e
BLAKE2b-256 e4a06582cda2eb7e57eb62595ea0ca4a809e9a756e20a47a0bd78c032bd58309

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