Skip to main content

Netzilo AI Detection & Response (AIDR) — governance for Python AI agents.

Project description

netzilo (Python)

Netzilo AI Detection & Response(AIDR) for Python

Provides full governance for custom AI agents written in Python

How it works

The Netzilo client is compiled to a native shared library and loaded in-process via ctypes. Every LLM prompt, model response, and tool call your agent makes can be evaluated — allowed, blocked, or redacted — against policy pulled live from your Netzilo management server. No daemon, no sidecar — nothing to stand up.

Install

pip install netzilo

Wheels are published per platform (Linux, macOS, Windows) and are independent of your Python version.

Core API

import netzilo

netzilo.start(server="https://srv.netzilo.com",   # management server
              pat="nzl_...",                       # or setup_key="..."
              agent_name="my-agent")               # non-blocking

netzilo.is_running()                       # -> bool: True once policy has synced (ready to govern)
netzilo.mcp_gateway_port()                 # -> int: scanner gateway port in use (auto-picked)
allowed, reason = netzilo.is_allowed("Bash", {"command": "rm -rf /"})
netzilo.report_result("Bash", "<stdout>")  # post-tool observability
netzilo.flush()                            # force-deliver buffered events to management
netzilo.snapshot()                         # force AIDR behavior-graph snapshot + delivery (else hourly/at-stop)
netzilo.stop()                             # graceful stop (snapshots graph + flushes events; auto-registered atexit)

Parameters may be passed as keyword args (above) or a single config dict. config_path defaults to ~/.netzilo-sdk/config.json; ports auto-pick free ports (governance on by default). is_running() returns True only after the initial policy sync — poll it before kicking off work.

Evaluation runs inside the processevaluate() calls the embedded engine directly, with no HTTP roundtrip and no local port to manage.

Advanced governance (enable_advanced_governance=True)

Framework adapters (below) govern at the tool/LLM-hook layer. Advanced governance adds deep inspection of the agent's own outbound traffic — covering every prompt, response, and tool call (including from subprocesses and libraries you have no hook for), with full content analysis and semantic classification:

netzilo.start(server=..., pat=..., agent_name=..., enable_advanced_governance=True)

It is fully automatic and requires no root and no changes to the host — the SDK prepares the process so the agent's traffic is inspected and continues to work normally. Inspected prompts/responses are analyzed and classified, emitting semantic.event records to your dashboard alongside the usual tool/LLM events. Default off; the framework adapters govern without it.

Framework adapters

Adapters are submodules of the one netzilo package — no separate installs. The framework is imported lazily inside each adapter (where it's imported at all — see below), so pip install netzilo never pulls in a framework you don't use.

Process-wide hooks

Register once; every tool call and LLM call made through the framework is governed from then on — no per-tool wrapping needed.

# CrewAI — registers before/after tool and LLM hooks process-wide
from netzilo.crewai import govern
govern(config={...})

# LangGraph — wrap nodes before compile()
import netzilo.langgraph
netzilo.langgraph.govern(graph, config={...})

# AutoGen — intervention handler
from netzilo.autogen import handler
runtime = SingleThreadedAgentRuntime(intervention_handlers=[handler(config={...})])

See CrewAI: local vs CrewAI AMP below for CrewAI's two deployment modes.

Tool-decorator frameworks

Where a framework's "tool" is a plain function wrapped by a decorator or a from_function()-style constructor, govern_tool() wraps the function itself. Apply it closer to the function than the framework's own decorator so schema inference still sees the original signature (functools.wraps preserves it):

from netzilo.llamaindex import govern, govern_tool
from llama_index.core.tools import FunctionTool

govern()  # starts the embedded client once, at boot

@govern_tool
def get_order_status(order_id: str) -> str:
    ...

tool = FunctionTool.from_defaults(fn=get_order_status)

The same pattern covers netzilo.langchain, netzilo.openai_agents (OpenAI Agents SDK), netzilo.google_adk, netzilo.pydantic_ai, netzilo.semantic_kernel, netzilo.smolagents, and netzilo.haystack — swap the import and the framework's own tool constructor/decorator, everything else is the same. netzilo.tools provides the same govern_tool() for any framework without a dedicated module. netzilo.langchain additionally exposes govern_model() for full prompt/response redaction at the LangChain chat-model boundary — see that module's docstring.

Raw LLM clients

For agents calling a provider's SDK directly with no framework in between, govern_client() patches the one call that sends a prompt so it's gated and redacted in place, then hands back the same client:

from netzilo.openai_sdk import govern, govern_client
from openai import OpenAI

govern()
client = govern_client(OpenAI())

resp = client.chat.completions.create(
    model="gpt-4o", messages=[{"role": "user", "content": "..."}]
)

Also available: netzilo.anthropic_sdk, netzilo.bedrock (AWS Bedrock runtime), netzilo.gemini (Google GenAI), netzilo.mistral — same govern() / govern_client() shape for each provider's own client and method.

Hook / middleware integrations

# LiteLLM — a CustomLogger registered into litellm.callbacks
from netzilo.litellm import govern, handler
import litellm
govern()
litellm.callbacks = [handler()]

# MCP — governs tool calls made through a ClientSession
from netzilo.mcp_client import govern, govern_session
session = govern_session(ClientSession(read_stream, write_stream))

# Guardrails AI — Netzilo as a Validator, composes with a Guard's own pipeline
from guardrails import Guard
from netzilo.guardrails import govern, validator
guard = Guard().use(validator(on_fail="fix"))

CrewAI: local vs CrewAI AMP

Local / self-hosted — put govern() once at the top of your entrypoint, before kickoff(). That's it.

import netzilo.crewai
netzilo.crewai.govern(config={"server": "...", "pat": "...", "agent_name": "my-agent"})

MyCrew().crew().kickoff(inputs={...})   # governed

CrewAI AMP — AMP's managed runtime only executes Flow @start/@listen methods; it skips module-level code, lifecycle hooks, and tool bodies. So the same govern() call goes inside a Flow @start step, then your crew runs in @listen. Deploy with [tool.crewai] type = "flow" in pyproject.toml, and always create the automation fresh as a flow (the type is locked at creation — re-pushing cannot convert an existing crew automation).

from crewai.flow import Flow, listen, start
import time

class MyFlow(Flow):

    @start()
    def init_governance(self):
        import netzilo, netzilo.crewai
        netzilo.crewai.govern(config={"server": "...", "pat": "...", "agent_name": "my-agent"})
        while not netzilo.is_running():   # wait until policy has synced
            time.sleep(0.5)

    @listen(init_governance)
    def run(self):
        return MyCrew().crew().kickoff(inputs={...})   # governed

Optional convenience extras pull a framework alongside netzilo, e.g. pip install netzilo[crewai], netzilo[langgraph], netzilo[llamaindex], netzilo[bedrock] — see [project.optional-dependencies] in pyproject.toml for the full list (one per adapter above). None of these are required: every adapter imports its framework lazily, so the extra is a convenience, not a dependency of the adapter itself.

Configuration

start() / govern() accept a config dict. Common keys:

Key Description
server Your Netzilo management server URL. (management_url is a legacy alias.)
pat / setup_key Credential used to enroll the agent.
agent_name Identifier this agent reports as (used for event attribution).
config_path Local client state (default: ~/.netzilo-sdk/config.json).
mcp_gateway_port Optional; defaults to an auto-picked free port. mcp_gateway_port=0 disables governance.
enable_advanced_governance Optional (default off). Deep inspection of the agent's own outbound traffic with semantic classification.
log_level / log_file Logging verbosity and destination.

Notes

The native library is bundled inside the wheel; pip selects the correct one for your platform automatically. Adapters ship inside the same wheel as submodules — a single distribution, not per-framework packages.

Netzilo is a commercial product. See https://www.netzilo.com.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

netzilo-4.3.15-py3-none-win_amd64.whl (26.0 MB view details)

Uploaded Python 3Windows x86-64

netzilo-4.3.15-py3-none-manylinux_2_28_x86_64.whl (34.5 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

netzilo-4.3.15-py3-none-manylinux_2_28_aarch64.whl (31.8 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

netzilo-4.3.15-py3-none-macosx_11_0_arm64.whl (23.5 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

netzilo-4.3.15-py3-none-macosx_10_13_x86_64.whl (25.4 MB view details)

Uploaded Python 3macOS 10.13+ x86-64

File details

Details for the file netzilo-4.3.15-py3-none-win_amd64.whl.

File metadata

  • Download URL: netzilo-4.3.15-py3-none-win_amd64.whl
  • Upload date:
  • Size: 26.0 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for netzilo-4.3.15-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 915f69d42ec3fbf19e526213f73f16f10eb3eac8d983b6bbe70fe1c24beca3b5
MD5 5561c25dad5a91101c04f65db49cc1cc
BLAKE2b-256 5e8e66107bdedc78ffb1398c22e299a99b5e3ede80c78d968b75eeb93dbf5193

See more details on using hashes here.

File details

Details for the file netzilo-4.3.15-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for netzilo-4.3.15-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5d0c24ec88f555c9edf47f0ba02504747ee30b6811d3fe4083234f63210b7b43
MD5 45c78201a78a50d2a00fef1d5d66bdb4
BLAKE2b-256 dd27d5efdecda7debaf6d4bfae3d569c9d26fdf276824673f5eea016a7da5f41

See more details on using hashes here.

File details

Details for the file netzilo-4.3.15-py3-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for netzilo-4.3.15-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8c3c3974639643bf5879b6e395b5a7079377e8d185c38c79ef5be401415927f7
MD5 c25f0973031c2e08ceae5e09341d767e
BLAKE2b-256 9546c3a942e52901e29d32598f223e35f3c47efa9c35dc501c80a0c6b6a459ee

See more details on using hashes here.

File details

Details for the file netzilo-4.3.15-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for netzilo-4.3.15-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ad11245756f7d573056c1292f9f36c8bc8af96ed122410a375c29153fcfc8464
MD5 14d23afcc136e7f8c837d22deefc19cd
BLAKE2b-256 5b483217892e3b4ecc73c65ba92073ad2dac3729afb6c9f4b553c4a1ee715b76

See more details on using hashes here.

File details

Details for the file netzilo-4.3.15-py3-none-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for netzilo-4.3.15-py3-none-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 dc6a6b20ceccb0abfb1b978410d0a14864f1276edcf8c967a359dccc8f9af304
MD5 5817c9b66201fce6cc072b7d2512dc6c
BLAKE2b-256 3c86429eedf2a25ce7959b5d2a80cb489858626e9d01ea7736410a1264d9d971

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