Metadata-Version: 2.4
Name: netzilo
Version: 4.3.15
Summary: Netzilo AI Detection & Response (AIDR) — governance for Python AI agents.
Author: Netzilo
License: Proprietary
Project-URL: Homepage, https://www.netzilo.com
Keywords: ai,agent,governance,security,aidr,netzilo
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: socksio>=1.0.0
Provides-Extra: crewai
Requires-Dist: crewai; extra == "crewai"
Provides-Extra: langgraph
Requires-Dist: langgraph; extra == "langgraph"
Provides-Extra: autogen
Requires-Dist: autogen-core; extra == "autogen"
Provides-Extra: langchain
Requires-Dist: langchain-core; extra == "langchain"
Provides-Extra: llamaindex
Requires-Dist: llama-index-core; extra == "llamaindex"
Provides-Extra: openai-agents
Requires-Dist: openai-agents; extra == "openai-agents"
Provides-Extra: google-adk
Requires-Dist: google-adk; extra == "google-adk"
Provides-Extra: pydantic-ai
Requires-Dist: pydantic-ai; extra == "pydantic-ai"
Provides-Extra: semantic-kernel
Requires-Dist: semantic-kernel; extra == "semantic-kernel"
Provides-Extra: smolagents
Requires-Dist: smolagents; extra == "smolagents"
Provides-Extra: haystack
Requires-Dist: haystack-ai; extra == "haystack"
Provides-Extra: openai-sdk
Requires-Dist: openai; extra == "openai-sdk"
Provides-Extra: anthropic-sdk
Requires-Dist: anthropic; extra == "anthropic-sdk"
Provides-Extra: bedrock
Requires-Dist: boto3; extra == "bedrock"
Provides-Extra: gemini
Requires-Dist: google-genai; extra == "gemini"
Provides-Extra: mistral
Requires-Dist: mistralai; extra == "mistral"
Provides-Extra: litellm
Requires-Dist: litellm; extra == "litellm"
Provides-Extra: mcp-client
Requires-Dist: mcp; extra == "mcp-client"
Provides-Extra: guardrails
Requires-Dist: guardrails-ai; extra == "guardrails"

# 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

```bash
pip install netzilo
```

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

## Core API

```python
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 process** — `evaluate()` 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:

```python
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.

```python
# 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](#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):

```python
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:

```python
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

```python
# 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.

```python
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).

```python
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>.
