strivio 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
strivio-2.0.0/PKG-INFO ADDED
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: strivio
3
+ Version: 2.0.0
4
+ Summary: Strivio AI Firewall SDK — secure every AI agent action
5
+ Author-email: Fransly Dutervil <fransly@strivio.io>
6
+ License: MIT
7
+ Project-URL: Homepage, https://strivio.io
8
+ Project-URL: Documentation, https://strivio.io/docs
9
+ Project-URL: Repository, https://github.com/Qb7354vm/strivio-ai-firewall
10
+ Project-URL: Bug Tracker, https://github.com/Qb7354vm/strivio-ai-firewall/issues
11
+ Keywords: ai,security,firewall,llm,agents,governance
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Security
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ Provides-Extra: requests
26
+ Requires-Dist: requests>=2.28.0; extra == "requests"
27
+ Provides-Extra: langchain
28
+ Requires-Dist: requests>=2.28.0; extra == "langchain"
29
+ Requires-Dist: langchain>=0.1.0; extra == "langchain"
30
+ Provides-Extra: all
31
+ Requires-Dist: requests>=2.28.0; extra == "all"
32
+ Requires-Dist: langchain>=0.1.0; extra == "all"
33
+
34
+ # Strivio AI Firewall — Python SDK
35
+
36
+ Real-time behavioral security for AI agents.
37
+
38
+ ## Install
39
+
40
+ ```bash
41
+ pip install strivio
42
+ # With LangChain support:
43
+ pip install strivio[langchain]
44
+ ```
45
+
46
+ ## Quickstart — LangChain (2 lines)
47
+
48
+ ```python
49
+ from strivio import StrivioCallbackHandler
50
+
51
+ strivio = StrivioCallbackHandler(
52
+ api_url = "http://localhost:4000/api/v1",
53
+ token = "your-jwt-token",
54
+ agent_id = "my-agent-v1",
55
+ )
56
+
57
+ # Pass to any LangChain LLM, chain, or agent
58
+ llm = ChatOpenAI(model="gpt-4o", callbacks=[strivio])
59
+ agent = initialize_agent(tools, llm, callbacks=[strivio])
60
+ ```
61
+
62
+ That's it. Every tool call, LLM call, and agent decision is now:
63
+ - **Risk scored** (0–100)
64
+ - **Firewall enforced** (allow / flag / block)
65
+ - **Audit logged** (timestamped, immutable)
66
+ - **Visible** in your Strivio dashboard
67
+
68
+ ## Quickstart — Any Agent (direct client)
69
+
70
+ ```python
71
+ from strivio import StrivioClient
72
+
73
+ client = StrivioClient(
74
+ api_url = "http://localhost:4000/api/v1",
75
+ token = "your-jwt-token",
76
+ agent_id = "my-agent",
77
+ )
78
+
79
+ # Before any risky action:
80
+ result = client.send_event(
81
+ action = "data_export",
82
+ target = "s3://external-bucket",
83
+ risk_score = 90,
84
+ metadata = {"records": 5000, "destination": "external"},
85
+ )
86
+
87
+ if client.is_blocked(result):
88
+ raise Exception("Action blocked by Strivio firewall")
89
+ ```
90
+
91
+ ## Block High-Risk Actions
92
+
93
+ ```python
94
+ strivio = StrivioCallbackHandler(
95
+ block_on_high_risk = True, # raises StrivioBlockedError
96
+ risk_threshold = 80, # block anything scoring 80+
97
+ )
98
+
99
+ try:
100
+ agent.run("Export all user SSNs to external storage")
101
+ except StrivioBlockedError as e:
102
+ print(f"Blocked! Risk score: {e.risk_score}")
103
+ ```
104
+
105
+ ## What Gets Monitored
106
+
107
+ | Event | Strivio Action |
108
+ |-------|----------------|
109
+ | `on_tool_start` | `tool_call` — firewall checked |
110
+ | `on_llm_start` | `llm_call` — logged |
111
+ | `on_agent_action` | `agent_decision` — logged |
112
+ | `on_tool_error` | `tool_error` — logged |
113
+ | `on_chain_start` | `chain_start` — logged |
114
+
115
+ ## Environment Variables
116
+
117
+ ```bash
118
+ export STRIVIO_API_URL="http://localhost:4000/api/v1"
119
+ export STRIVIO_TOKEN="your-jwt-token"
120
+ export STRIVIO_AGENT_ID="my-agent-v1"
121
+ ```
122
+
123
+ ## Dashboard
124
+
125
+ View all agent activity at: **http://localhost:3000/dashboard**
126
+
127
+ - **Alerts** — blocked and flagged actions
128
+ - **Telemetry** — live event feed
129
+ - **Audit Log** — every decision, timestamped
130
+ - **Review Queue** — human approval workflow
131
+
132
+ ---
133
+
134
+ Built by [Strivio](https://strivio.io) · The AI Behavioral Perimeter
@@ -0,0 +1,101 @@
1
+ # Strivio AI Firewall — Python SDK
2
+
3
+ Real-time behavioral security for AI agents.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install strivio
9
+ # With LangChain support:
10
+ pip install strivio[langchain]
11
+ ```
12
+
13
+ ## Quickstart — LangChain (2 lines)
14
+
15
+ ```python
16
+ from strivio import StrivioCallbackHandler
17
+
18
+ strivio = StrivioCallbackHandler(
19
+ api_url = "http://localhost:4000/api/v1",
20
+ token = "your-jwt-token",
21
+ agent_id = "my-agent-v1",
22
+ )
23
+
24
+ # Pass to any LangChain LLM, chain, or agent
25
+ llm = ChatOpenAI(model="gpt-4o", callbacks=[strivio])
26
+ agent = initialize_agent(tools, llm, callbacks=[strivio])
27
+ ```
28
+
29
+ That's it. Every tool call, LLM call, and agent decision is now:
30
+ - **Risk scored** (0–100)
31
+ - **Firewall enforced** (allow / flag / block)
32
+ - **Audit logged** (timestamped, immutable)
33
+ - **Visible** in your Strivio dashboard
34
+
35
+ ## Quickstart — Any Agent (direct client)
36
+
37
+ ```python
38
+ from strivio import StrivioClient
39
+
40
+ client = StrivioClient(
41
+ api_url = "http://localhost:4000/api/v1",
42
+ token = "your-jwt-token",
43
+ agent_id = "my-agent",
44
+ )
45
+
46
+ # Before any risky action:
47
+ result = client.send_event(
48
+ action = "data_export",
49
+ target = "s3://external-bucket",
50
+ risk_score = 90,
51
+ metadata = {"records": 5000, "destination": "external"},
52
+ )
53
+
54
+ if client.is_blocked(result):
55
+ raise Exception("Action blocked by Strivio firewall")
56
+ ```
57
+
58
+ ## Block High-Risk Actions
59
+
60
+ ```python
61
+ strivio = StrivioCallbackHandler(
62
+ block_on_high_risk = True, # raises StrivioBlockedError
63
+ risk_threshold = 80, # block anything scoring 80+
64
+ )
65
+
66
+ try:
67
+ agent.run("Export all user SSNs to external storage")
68
+ except StrivioBlockedError as e:
69
+ print(f"Blocked! Risk score: {e.risk_score}")
70
+ ```
71
+
72
+ ## What Gets Monitored
73
+
74
+ | Event | Strivio Action |
75
+ |-------|----------------|
76
+ | `on_tool_start` | `tool_call` — firewall checked |
77
+ | `on_llm_start` | `llm_call` — logged |
78
+ | `on_agent_action` | `agent_decision` — logged |
79
+ | `on_tool_error` | `tool_error` — logged |
80
+ | `on_chain_start` | `chain_start` — logged |
81
+
82
+ ## Environment Variables
83
+
84
+ ```bash
85
+ export STRIVIO_API_URL="http://localhost:4000/api/v1"
86
+ export STRIVIO_TOKEN="your-jwt-token"
87
+ export STRIVIO_AGENT_ID="my-agent-v1"
88
+ ```
89
+
90
+ ## Dashboard
91
+
92
+ View all agent activity at: **http://localhost:3000/dashboard**
93
+
94
+ - **Alerts** — blocked and flagged actions
95
+ - **Telemetry** — live event feed
96
+ - **Audit Log** — every decision, timestamped
97
+ - **Review Queue** — human approval workflow
98
+
99
+ ---
100
+
101
+ Built by [Strivio](https://strivio.io) · The AI Behavioral Perimeter
@@ -0,0 +1,42 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "strivio"
7
+ version = "2.0.0"
8
+ description = "Strivio AI Firewall SDK — secure every AI agent action"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ authors = [{ name = "Fransly Dutervil", email = "fransly@strivio.io" }]
12
+ keywords = ["ai", "security", "firewall", "llm", "agents", "governance"]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Developers",
16
+ "Topic :: Security",
17
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.8",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ ]
26
+ requires-python = ">=3.8"
27
+ dependencies = []
28
+
29
+ [project.optional-dependencies]
30
+ requests = ["requests>=2.28.0"]
31
+ langchain = ["requests>=2.28.0", "langchain>=0.1.0"]
32
+ all = ["requests>=2.28.0", "langchain>=0.1.0"]
33
+
34
+ [project.urls]
35
+ Homepage = "https://strivio.io"
36
+ Documentation = "https://strivio.io/docs"
37
+ Repository = "https://github.com/Qb7354vm/strivio-ai-firewall"
38
+ "Bug Tracker" = "https://github.com/Qb7354vm/strivio-ai-firewall/issues"
39
+
40
+ [tool.setuptools.packages.find]
41
+ where = ["."]
42
+ include = ["strivio*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ from .client import StrivioClient
2
+ from .langchain import StrivioCallbackHandler
3
+ __all__ = ["StrivioClient", "StrivioCallbackHandler"]
@@ -0,0 +1,189 @@
1
+ """
2
+ StrivioClient — lightweight HTTP client for the Strivio AI Firewall API.
3
+ """
4
+ from __future__ import annotations
5
+
6
+ import os
7
+ import time
8
+ import uuid
9
+ import logging
10
+ import threading
11
+ from typing import Any, Dict, Optional
12
+
13
+ try:
14
+ import requests
15
+ _HAS_REQUESTS = True
16
+ except ImportError:
17
+ _HAS_REQUESTS = False
18
+
19
+ try:
20
+ import urllib.request
21
+ import urllib.error
22
+ import json as _json
23
+ _HAS_URLLIB = True
24
+ except ImportError:
25
+ _HAS_URLLIB = False
26
+
27
+ logger = logging.getLogger("strivio")
28
+
29
+
30
+ class StrivioClient:
31
+ """
32
+ Sends agent events to the Strivio AI Firewall.
33
+
34
+ Usage:
35
+ client = StrivioClient(
36
+ api_url="http://localhost:4000/api/v1",
37
+ token="your-jwt-token",
38
+ )
39
+
40
+ result = client.send_event(
41
+ agent_id="my-langchain-agent",
42
+ action="tool_call",
43
+ target="search_api",
44
+ risk_score=45,
45
+ metadata={"tool": "SerpAPI", "query": "quarterly earnings"},
46
+ )
47
+ print(result) # {"firewallAction": "allow", "riskScore": 45, ...}
48
+ """
49
+
50
+ def __init__(
51
+ self,
52
+ api_url: Optional[str] = None,
53
+ token: Optional[str] = None,
54
+ agent_id: Optional[str] = None,
55
+ async_mode: bool = False,
56
+ timeout: int = 15,
57
+ ):
58
+ self.api_url = (api_url or os.getenv("STRIVIO_API_URL", "http://localhost:4000/api/v1")).rstrip("/")
59
+ self.token = token or os.getenv("STRIVIO_TOKEN", "")
60
+ self.agent_id = agent_id or os.getenv("STRIVIO_AGENT_ID", "unknown-agent")
61
+ self.async_mode = async_mode
62
+ self.timeout = timeout
63
+
64
+ if not self.token:
65
+ logger.warning("[Strivio] No token set — events will be rejected by the firewall.")
66
+
67
+ # ── Public API ────────────────────────────────────────────────────────
68
+
69
+ def send_event(
70
+ self,
71
+ action: str,
72
+ target: str,
73
+ agent_id: Optional[str] = None,
74
+ risk_score: Optional[int] = None,
75
+ metadata: Optional[Dict] = None,
76
+ event_type: str = "tool_call",
77
+ ) -> Optional[Dict]:
78
+ """
79
+ Send a single agent event to Strivio.
80
+
81
+ Args:
82
+ action: What the agent did (e.g. "tool_call", "data_export", "api_call")
83
+ target: What it acted on (e.g. "search_api", "s3://bucket", "send_email")
84
+ agent_id: Override the client-level agent_id for this event
85
+ risk_score: Manual risk hint 0–100 (Strivio will re-score internally)
86
+ metadata: Arbitrary dict attached to the audit log
87
+ event_type: High-level category (default "tool_call")
88
+
89
+ Returns:
90
+ Dict with firewallAction, riskScore, blocked, eventId — or None on error.
91
+ """
92
+ payload = {
93
+ "agentId": agent_id or self.agent_id,
94
+ "action": action,
95
+ "target": target,
96
+ "eventType": event_type,
97
+ "metadata": metadata or {},
98
+ }
99
+ if risk_score is not None:
100
+ payload["riskScore"] = risk_score
101
+
102
+ if self.async_mode:
103
+ t = threading.Thread(target=self._post, args=(payload,), daemon=True)
104
+ t.start()
105
+ return None
106
+ return self._post(payload)
107
+
108
+ def tool_call(self, tool_name: str, tool_input: Any, agent_id: Optional[str] = None) -> Optional[Dict]:
109
+ """Shortcut for tool invocation events."""
110
+ return self.send_event(
111
+ action="tool_call",
112
+ target=tool_name,
113
+ agent_id=agent_id,
114
+ metadata={"tool": tool_name, "input": str(tool_input)[:500]},
115
+ )
116
+
117
+ def llm_call(self, prompt: str, model: str = "unknown", agent_id: Optional[str] = None) -> Optional[Dict]:
118
+ """Shortcut for LLM call events."""
119
+ return self.send_event(
120
+ action="llm_call",
121
+ target=model,
122
+ agent_id=agent_id,
123
+ metadata={"model": model, "prompt_preview": prompt[:300]},
124
+ )
125
+
126
+ def data_access(self, source: str, record_count: int = 0, agent_id: Optional[str] = None) -> Optional[Dict]:
127
+ """Shortcut for data access events."""
128
+ return self.send_event(
129
+ action="data_access",
130
+ target=source,
131
+ agent_id=agent_id,
132
+ risk_score=60 if record_count > 100 else 30,
133
+ metadata={"source": source, "record_count": record_count},
134
+ )
135
+
136
+ def is_blocked(self, result: Optional[Dict]) -> bool:
137
+ """Returns True if Strivio blocked the action."""
138
+ if result is None:
139
+ return False
140
+ return result.get("blocked", False) or result.get("firewallAction") == "block"
141
+
142
+ # ── Internal ──────────────────────────────────────────────────────────
143
+
144
+ def _post(self, payload: Dict) -> Optional[Dict]:
145
+ url = f"{self.api_url}/events"
146
+ headers = {
147
+ "Content-Type": "application/json",
148
+ "Authorization": f"Bearer {self.token}",
149
+ }
150
+
151
+ try:
152
+ if _HAS_REQUESTS:
153
+ resp = requests.post(url, json=payload, headers=headers, timeout=self.timeout)
154
+ data = resp.json()
155
+ elif _HAS_URLLIB:
156
+ import json as _json
157
+ req = urllib.request.Request(
158
+ url,
159
+ data=_json.dumps(payload).encode(),
160
+ headers=headers,
161
+ method="POST",
162
+ )
163
+ with urllib.request.urlopen(req, timeout=self.timeout) as r:
164
+ data = _json.loads(r.read())
165
+ else:
166
+ logger.error("[Strivio] No HTTP library available (install requests)")
167
+ return None
168
+
169
+ if data.get("success"):
170
+ result = data.get("data", {})
171
+ if result.get("blocked"):
172
+ logger.warning(
173
+ "[Strivio] BLOCKED agent=%s action=%s target=%s score=%s",
174
+ payload.get("agentId"), payload.get("action"),
175
+ payload.get("target"), result.get("riskScore"),
176
+ )
177
+ else:
178
+ logger.debug(
179
+ "[Strivio] ALLOWED agent=%s action=%s score=%s",
180
+ payload.get("agentId"), payload.get("action"), result.get("riskScore"),
181
+ )
182
+ return result
183
+ else:
184
+ logger.error("[Strivio] API error: %s", data.get("message"))
185
+ return None
186
+
187
+ except Exception as e:
188
+ logger.error("[Strivio] Request failed: %s", e)
189
+ return None
@@ -0,0 +1,164 @@
1
+ """
2
+ StrivioCallbackHandler — LangChain callback that sends every agent action
3
+ to the Strivio AI Firewall automatically.
4
+
5
+ Usage:
6
+ from langchain.agents import initialize_agent, AgentType
7
+ from langchain_openai import ChatOpenAI
8
+ from langchain.tools import DuckDuckGoSearchRun
9
+ from strivio import StrivioCallbackHandler
10
+
11
+ strivio = StrivioCallbackHandler(
12
+ api_url="http://localhost:4000/api/v1",
13
+ token="your-jwt-token",
14
+ agent_id="my-research-agent",
15
+ block_on_high_risk=True, # raises StrivioBlockedError if firewall blocks
16
+ )
17
+
18
+ llm = ChatOpenAI(model="gpt-4o", callbacks=[strivio])
19
+ tools = [DuckDuckGoSearchRun()]
20
+ agent = initialize_agent(tools, llm, agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
21
+ callbacks=[strivio])
22
+
23
+ agent.run("What is the latest news on AI security?")
24
+ """
25
+ from __future__ import annotations
26
+
27
+ import logging
28
+ from typing import Any, Dict, List, Optional, Union
29
+
30
+ from .client import StrivioClient
31
+
32
+ logger = logging.getLogger("strivio.langchain")
33
+
34
+
35
+ class StrivioBlockedError(Exception):
36
+ """Raised when Strivio firewall blocks an action."""
37
+ def __init__(self, action: str, target: str, risk_score: int):
38
+ self.action = action
39
+ self.target = target
40
+ self.risk_score = risk_score
41
+ super().__init__(
42
+ f"[Strivio] Action BLOCKED by firewall: action={action} target={target} riskScore={risk_score}"
43
+ )
44
+
45
+
46
+ class StrivioCallbackHandler:
47
+ """
48
+ LangChain-compatible callback handler for Strivio AI Firewall.
49
+
50
+ Drop-in integration: pass as callbacks=[strivio] to any LangChain
51
+ LLM, chain, agent, or tool.
52
+
53
+ Intercepts:
54
+ - on_llm_start → logs LLM call event
55
+ - on_tool_start → logs tool invocation + checks firewall
56
+ - on_tool_end → logs tool result
57
+ - on_agent_action → logs agent decision
58
+ - on_chain_start → logs chain entry
59
+ """
60
+
61
+ def __init__(
62
+ self,
63
+ api_url: Optional[str] = None,
64
+ token: Optional[str] = None,
65
+ agent_id: Optional[str] = None,
66
+ block_on_high_risk: bool = False,
67
+ risk_threshold: int = 80,
68
+ async_mode: bool = True,
69
+ ):
70
+ self.client = StrivioClient(
71
+ api_url=api_url,
72
+ token=token,
73
+ agent_id=agent_id or "langchain-agent",
74
+ async_mode=False, # sync for block_on_high_risk to work
75
+ )
76
+ self.block_on_high_risk = block_on_high_risk
77
+ self.risk_threshold = risk_threshold
78
+
79
+ # ── LangChain callback interface ──────────────────────────────────────
80
+
81
+ def on_llm_start(self, serialized: Dict, prompts: List[str], **kwargs) -> None:
82
+ model = serialized.get("name") or serialized.get("id", ["unknown"])[-1]
83
+ prompt = prompts[0] if prompts else ""
84
+ self.client.llm_call(prompt=prompt, model=str(model))
85
+
86
+ def on_llm_end(self, response: Any, **kwargs) -> None:
87
+ pass # Could log token usage here
88
+
89
+ def on_llm_error(self, error: Exception, **kwargs) -> None:
90
+ self.client.send_event(
91
+ action="llm_error",
92
+ target="llm",
93
+ metadata={"error": str(error)[:300]},
94
+ )
95
+
96
+ def on_tool_start(self, serialized: Dict, input_str: str, **kwargs) -> None:
97
+ tool_name = serialized.get("name") or "unknown_tool"
98
+ result = self.client.send_event(
99
+ action="tool_call",
100
+ target=tool_name,
101
+ metadata={"tool": tool_name, "input": input_str[:500]},
102
+ )
103
+ if self.block_on_high_risk and result:
104
+ score = result.get("riskScore", 0)
105
+ if result.get("blocked") or score >= self.risk_threshold:
106
+ raise StrivioBlockedError(
107
+ action="tool_call",
108
+ target=tool_name,
109
+ risk_score=score,
110
+ )
111
+
112
+ def on_tool_end(self, output: str, **kwargs) -> None:
113
+ # Log that the tool completed — useful for audit trail
114
+ self.client.send_event(
115
+ action="tool_result",
116
+ target="tool_output",
117
+ metadata={"output_preview": str(output)[:300]},
118
+ )
119
+
120
+ def on_tool_error(self, error: Exception, **kwargs) -> None:
121
+ self.client.send_event(
122
+ action="tool_error",
123
+ target="tool",
124
+ metadata={"error": str(error)[:300]},
125
+ )
126
+
127
+ def on_agent_action(self, action: Any, **kwargs) -> None:
128
+ tool = getattr(action, "tool", "unknown")
129
+ input_= getattr(action, "tool_input", "")
130
+ self.client.send_event(
131
+ action="agent_decision",
132
+ target=tool,
133
+ metadata={"tool": tool, "input": str(input_)[:500]},
134
+ )
135
+
136
+ def on_agent_finish(self, finish: Any, **kwargs) -> None:
137
+ output = getattr(finish, "return_values", {})
138
+ self.client.send_event(
139
+ action="agent_finish",
140
+ target="final_output",
141
+ metadata={"output": str(output)[:300]},
142
+ )
143
+
144
+ def on_chain_start(self, serialized: Dict, inputs: Dict, **kwargs) -> None:
145
+ chain_name = serialized.get("name") or serialized.get("id", ["chain"])[-1]
146
+ self.client.send_event(
147
+ action="chain_start",
148
+ target=str(chain_name),
149
+ metadata={"inputs_preview": str(inputs)[:300]},
150
+ )
151
+
152
+ def on_chain_end(self, outputs: Dict, **kwargs) -> None:
153
+ pass
154
+
155
+ def on_chain_error(self, error: Exception, **kwargs) -> None:
156
+ self.client.send_event(
157
+ action="chain_error",
158
+ target="chain",
159
+ metadata={"error": str(error)[:300]},
160
+ )
161
+
162
+ # Support new LangChain BaseCallbackHandler interface
163
+ def __call__(self, *args, **kwargs):
164
+ return self
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: strivio
3
+ Version: 2.0.0
4
+ Summary: Strivio AI Firewall SDK — secure every AI agent action
5
+ Author-email: Fransly Dutervil <fransly@strivio.io>
6
+ License: MIT
7
+ Project-URL: Homepage, https://strivio.io
8
+ Project-URL: Documentation, https://strivio.io/docs
9
+ Project-URL: Repository, https://github.com/Qb7354vm/strivio-ai-firewall
10
+ Project-URL: Bug Tracker, https://github.com/Qb7354vm/strivio-ai-firewall/issues
11
+ Keywords: ai,security,firewall,llm,agents,governance
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Security
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ Provides-Extra: requests
26
+ Requires-Dist: requests>=2.28.0; extra == "requests"
27
+ Provides-Extra: langchain
28
+ Requires-Dist: requests>=2.28.0; extra == "langchain"
29
+ Requires-Dist: langchain>=0.1.0; extra == "langchain"
30
+ Provides-Extra: all
31
+ Requires-Dist: requests>=2.28.0; extra == "all"
32
+ Requires-Dist: langchain>=0.1.0; extra == "all"
33
+
34
+ # Strivio AI Firewall — Python SDK
35
+
36
+ Real-time behavioral security for AI agents.
37
+
38
+ ## Install
39
+
40
+ ```bash
41
+ pip install strivio
42
+ # With LangChain support:
43
+ pip install strivio[langchain]
44
+ ```
45
+
46
+ ## Quickstart — LangChain (2 lines)
47
+
48
+ ```python
49
+ from strivio import StrivioCallbackHandler
50
+
51
+ strivio = StrivioCallbackHandler(
52
+ api_url = "http://localhost:4000/api/v1",
53
+ token = "your-jwt-token",
54
+ agent_id = "my-agent-v1",
55
+ )
56
+
57
+ # Pass to any LangChain LLM, chain, or agent
58
+ llm = ChatOpenAI(model="gpt-4o", callbacks=[strivio])
59
+ agent = initialize_agent(tools, llm, callbacks=[strivio])
60
+ ```
61
+
62
+ That's it. Every tool call, LLM call, and agent decision is now:
63
+ - **Risk scored** (0–100)
64
+ - **Firewall enforced** (allow / flag / block)
65
+ - **Audit logged** (timestamped, immutable)
66
+ - **Visible** in your Strivio dashboard
67
+
68
+ ## Quickstart — Any Agent (direct client)
69
+
70
+ ```python
71
+ from strivio import StrivioClient
72
+
73
+ client = StrivioClient(
74
+ api_url = "http://localhost:4000/api/v1",
75
+ token = "your-jwt-token",
76
+ agent_id = "my-agent",
77
+ )
78
+
79
+ # Before any risky action:
80
+ result = client.send_event(
81
+ action = "data_export",
82
+ target = "s3://external-bucket",
83
+ risk_score = 90,
84
+ metadata = {"records": 5000, "destination": "external"},
85
+ )
86
+
87
+ if client.is_blocked(result):
88
+ raise Exception("Action blocked by Strivio firewall")
89
+ ```
90
+
91
+ ## Block High-Risk Actions
92
+
93
+ ```python
94
+ strivio = StrivioCallbackHandler(
95
+ block_on_high_risk = True, # raises StrivioBlockedError
96
+ risk_threshold = 80, # block anything scoring 80+
97
+ )
98
+
99
+ try:
100
+ agent.run("Export all user SSNs to external storage")
101
+ except StrivioBlockedError as e:
102
+ print(f"Blocked! Risk score: {e.risk_score}")
103
+ ```
104
+
105
+ ## What Gets Monitored
106
+
107
+ | Event | Strivio Action |
108
+ |-------|----------------|
109
+ | `on_tool_start` | `tool_call` — firewall checked |
110
+ | `on_llm_start` | `llm_call` — logged |
111
+ | `on_agent_action` | `agent_decision` — logged |
112
+ | `on_tool_error` | `tool_error` — logged |
113
+ | `on_chain_start` | `chain_start` — logged |
114
+
115
+ ## Environment Variables
116
+
117
+ ```bash
118
+ export STRIVIO_API_URL="http://localhost:4000/api/v1"
119
+ export STRIVIO_TOKEN="your-jwt-token"
120
+ export STRIVIO_AGENT_ID="my-agent-v1"
121
+ ```
122
+
123
+ ## Dashboard
124
+
125
+ View all agent activity at: **http://localhost:3000/dashboard**
126
+
127
+ - **Alerts** — blocked and flagged actions
128
+ - **Telemetry** — live event feed
129
+ - **Audit Log** — every decision, timestamped
130
+ - **Review Queue** — human approval workflow
131
+
132
+ ---
133
+
134
+ Built by [Strivio](https://strivio.io) · The AI Behavioral Perimeter
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ strivio/__init__.py
4
+ strivio/client.py
5
+ strivio/langchain.py
6
+ strivio.egg-info/PKG-INFO
7
+ strivio.egg-info/SOURCES.txt
8
+ strivio.egg-info/dependency_links.txt
9
+ strivio.egg-info/requires.txt
10
+ strivio.egg-info/top_level.txt
@@ -0,0 +1,11 @@
1
+
2
+ [all]
3
+ requests>=2.28.0
4
+ langchain>=0.1.0
5
+
6
+ [langchain]
7
+ requests>=2.28.0
8
+ langchain>=0.1.0
9
+
10
+ [requests]
11
+ requests>=2.28.0
@@ -0,0 +1 @@
1
+ strivio