stackone-defender 0.7.0__tar.gz → 0.7.2__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.
- stackone_defender-0.7.2/.release-please-manifest.json +1 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/CHANGELOG.md +23 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/PKG-INFO +14 -1
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/README.md +13 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/pyproject.toml +1 -1
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/__init__.py +17 -1
- stackone_defender-0.7.2/src/stackone_defender/classifiers/tier3_orchestrator.py +27 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/core/prompt_defense.py +443 -20
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/types.py +64 -1
- stackone_defender-0.7.2/tests/test_tier3.py +459 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/uv.lock +1 -1
- stackone_defender-0.7.0/.release-please-manifest.json +0 -1
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/.github/workflows/ci.yaml +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/.github/workflows/release.yaml +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/.gitignore +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/.python-version +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/.release-please-config.json +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/models/minilm-full-aug/config.json +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/models/minilm-full-aug/model_quantized.onnx +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/models/minilm-full-aug/tokenizer.json +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/models/minilm-full-aug/tokenizer_config.json +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/classifiers/__init__.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/classifiers/onnx_classifier.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/classifiers/pattern_detector.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/classifiers/patterns.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/classifiers/tier2_classifier.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/config.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/core/__init__.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/core/tool_result_sanitizer.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/models/minilm-multihead-v5/classifier_config.json +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/models/minilm-multihead-v5/config.json +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/models/minilm-multihead-v5/model_quantized.onnx +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/models/minilm-multihead-v5/tokenizer.json +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/models/minilm-multihead-v5/tokenizer_config.json +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/sanitizers/__init__.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/sanitizers/encoding_detector.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/sanitizers/leet_normalizer.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/sanitizers/normalizer.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/sanitizers/pattern_remover.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/sanitizers/role_stripper.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/sanitizers/sanitizer.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/sfe/__init__.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/sfe/model.ftz +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/sfe/preprocess.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/utils/__init__.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/utils/boundary.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/utils/field_detection.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/src/stackone_defender/utils/structure.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/tests/__init__.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/tests/test_integration.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/tests/test_onnx_classifier.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/tests/test_pattern_detector.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/tests/test_sanitizers.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/tests/test_sfe.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/tests/test_tier2_classifier.py +0 -0
- {stackone_defender-0.7.0 → stackone_defender-0.7.2}/tests/test_utils.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{".":"0.7.2"}
|
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.7.2](https://github.com/StackOneHQ/stackone-defender/compare/stackone-defender-v0.7.1...stackone-defender-v0.7.2) (2026-06-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add Tier3Verdict.usage for TS 0.7.2 parity ([2e18269](https://github.com/StackOneHQ/stackone-defender/commit/2e182695c20e9b087041e55f7466cca9b659521a))
|
|
9
|
+
* Tier3Verdict.usage parity with @stackone/defender 0.7.2 ([1c9c0c8](https://github.com/StackOneHQ/stackone-defender/commit/1c9c0c8026fd8c4dda2f78c31a1f500c01045d43))
|
|
10
|
+
|
|
11
|
+
## [0.7.1](https://github.com/StackOneHQ/stackone-defender/compare/stackone-defender-v0.7.0...stackone-defender-v0.7.1) (2026-06-16)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* add defend_tool_results_async for npm batch parity ([a05783c](https://github.com/StackOneHQ/stackone-defender/commit/a05783c5671548aa66dfead1f129584b249d8778))
|
|
17
|
+
* Python parity with @stackone/defender 0.7.1 (Tier 3) ([c58a17c](https://github.com/StackOneHQ/stackone-defender/commit/c58a17c9ba1a902148cde9204666f7f1a916d09b))
|
|
18
|
+
* Tier 3 provider interface and cascade orchestration (TS 0.7.1 parity) ([f2b4109](https://github.com/StackOneHQ/stackone-defender/commit/f2b41096db4ca65741b9d4ba62f3fad7591929ab))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* address Copilot PR review on Tier 3 orchestration ([570f567](https://github.com/StackOneHQ/stackone-defender/commit/570f56753292700a15b73725a12db426316468c6))
|
|
24
|
+
* tighten Tier3ClassifyResult type and batch doc wording ([2515772](https://github.com/StackOneHQ/stackone-defender/commit/2515772f894dd2cbdaa51e9d0b39e26f151d257f))
|
|
25
|
+
|
|
3
26
|
## [0.7.0](https://github.com/StackOneHQ/stackone-defender/compare/stackone-defender-v0.6.3...stackone-defender-v0.7.0) (2026-05-29)
|
|
4
27
|
|
|
5
28
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stackone-defender
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.2
|
|
4
4
|
Summary: Indirect prompt injection defense for AI agents using tool calls
|
|
5
5
|
Project-URL: Homepage, https://github.com/StackOneHQ/stackone-defender
|
|
6
6
|
Project-URL: Repository, https://github.com/StackOneHQ/stackone-defender
|
|
@@ -204,6 +204,8 @@ class DefenseResult:
|
|
|
204
204
|
|
|
205
205
|
### `defense.defend_tool_results(items)`
|
|
206
206
|
|
|
207
|
+
Sync batch API. When `enable_tier3=True`, uses one `asyncio.run()` and defends items **concurrently** via `asyncio.gather` (same scheduling model as npm `defendToolResults`; blocking sync providers still run one at a time on the event-loop thread). From async code, prefer `defend_tool_results_async`.
|
|
208
|
+
|
|
207
209
|
```python
|
|
208
210
|
results = defense.defend_tool_results([
|
|
209
211
|
{"value": email_data, "tool_name": "gmail_get_message"},
|
|
@@ -215,6 +217,17 @@ for r in results:
|
|
|
215
217
|
print("Blocked:", ", ".join(r.fields_sanitized))
|
|
216
218
|
```
|
|
217
219
|
|
|
220
|
+
### `await defense.defend_tool_results_async(items)`
|
|
221
|
+
|
|
222
|
+
Async batch API — runs `defend_tool_result_async` per item concurrently via `asyncio.gather`. Required when Tier 3 is enabled inside a running event loop (e.g. FastAPI).
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
results = await defense.defend_tool_results_async([
|
|
226
|
+
{"value": email_data, "tool_name": "gmail_get_message"},
|
|
227
|
+
{"value": doc_data, "tool_name": "documents_get"},
|
|
228
|
+
])
|
|
229
|
+
```
|
|
230
|
+
|
|
218
231
|
### `defense.analyze(text)`
|
|
219
232
|
|
|
220
233
|
Tier 1 only — useful for debugging pattern hits without full tool-result traversal.
|
|
@@ -178,6 +178,8 @@ class DefenseResult:
|
|
|
178
178
|
|
|
179
179
|
### `defense.defend_tool_results(items)`
|
|
180
180
|
|
|
181
|
+
Sync batch API. When `enable_tier3=True`, uses one `asyncio.run()` and defends items **concurrently** via `asyncio.gather` (same scheduling model as npm `defendToolResults`; blocking sync providers still run one at a time on the event-loop thread). From async code, prefer `defend_tool_results_async`.
|
|
182
|
+
|
|
181
183
|
```python
|
|
182
184
|
results = defense.defend_tool_results([
|
|
183
185
|
{"value": email_data, "tool_name": "gmail_get_message"},
|
|
@@ -189,6 +191,17 @@ for r in results:
|
|
|
189
191
|
print("Blocked:", ", ".join(r.fields_sanitized))
|
|
190
192
|
```
|
|
191
193
|
|
|
194
|
+
### `await defense.defend_tool_results_async(items)`
|
|
195
|
+
|
|
196
|
+
Async batch API — runs `defend_tool_result_async` per item concurrently via `asyncio.gather`. Required when Tier 3 is enabled inside a running event loop (e.g. FastAPI).
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
results = await defense.defend_tool_results_async([
|
|
200
|
+
{"value": email_data, "tool_name": "gmail_get_message"},
|
|
201
|
+
{"value": doc_data, "tool_name": "documents_get"},
|
|
202
|
+
])
|
|
203
|
+
```
|
|
204
|
+
|
|
192
205
|
### `defense.analyze(text)`
|
|
193
206
|
|
|
194
207
|
Tier 1 only — useful for debugging pattern hits without full tool-result traversal.
|
|
@@ -12,6 +12,7 @@ Usage:
|
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
from .classifiers.onnx_classifier import get_default_model_path
|
|
15
|
+
from .classifiers.tier3_orchestrator import get_default_tier3_provider, set_default_tier3_provider
|
|
15
16
|
from .core.prompt_defense import PromptDefense, create_prompt_defense
|
|
16
17
|
from .sfe.preprocess import (
|
|
17
18
|
DropDecision,
|
|
@@ -21,10 +22,20 @@ from .sfe.preprocess import (
|
|
|
21
22
|
get_default_sfe_model_path,
|
|
22
23
|
sfe_preprocess,
|
|
23
24
|
)
|
|
24
|
-
from .types import
|
|
25
|
+
from .types import (
|
|
26
|
+
DefenderMode,
|
|
27
|
+
DefenseResult,
|
|
28
|
+
MultiheadConfig,
|
|
29
|
+
RiskLevel,
|
|
30
|
+
Tier1Result,
|
|
31
|
+
Tier3Provider,
|
|
32
|
+
Tier3TokenUsage,
|
|
33
|
+
Tier3Verdict,
|
|
34
|
+
)
|
|
25
35
|
from .utils.boundary import contains_boundary_patterns, generate_boundary_instructions
|
|
26
36
|
|
|
27
37
|
__all__ = [
|
|
38
|
+
"DefenderMode",
|
|
28
39
|
"DefenseResult",
|
|
29
40
|
"DropDecision",
|
|
30
41
|
"MultiheadConfig",
|
|
@@ -33,11 +44,16 @@ __all__ = [
|
|
|
33
44
|
"SfePredictor",
|
|
34
45
|
"SfePreprocessResult",
|
|
35
46
|
"Tier1Result",
|
|
47
|
+
"Tier3Provider",
|
|
48
|
+
"Tier3TokenUsage",
|
|
49
|
+
"Tier3Verdict",
|
|
36
50
|
"contains_boundary_patterns",
|
|
37
51
|
"create_prompt_defense",
|
|
38
52
|
"generate_boundary_instructions",
|
|
39
53
|
"get_default_model_path",
|
|
40
54
|
"get_default_predictor",
|
|
41
55
|
"get_default_sfe_model_path",
|
|
56
|
+
"get_default_tier3_provider",
|
|
57
|
+
"set_default_tier3_provider",
|
|
42
58
|
"sfe_preprocess",
|
|
43
59
|
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Tier 3 provider registry.
|
|
2
|
+
|
|
3
|
+
The defender package ships no Tier 3 implementations — proprietary model
|
|
4
|
+
endpoints (SageMaker, OpenAI, etc.) live in consumer code. Consumers call
|
|
5
|
+
``set_default_tier3_provider(provider)`` once at app startup; ``PromptDefense``
|
|
6
|
+
picks the registered provider up when callers opt in via ``enable_tier3=True``.
|
|
7
|
+
|
|
8
|
+
Module-level singleton because the defender is often instantiated per-request
|
|
9
|
+
and we don't want to pipe a provider object through that boundary on every call.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from ..types import Tier3Provider
|
|
15
|
+
|
|
16
|
+
_default_provider: Tier3Provider | None = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def set_default_tier3_provider(provider: Tier3Provider | None) -> None:
|
|
20
|
+
"""Register the process-wide default Tier 3 provider. Pass ``None`` to clear."""
|
|
21
|
+
global _default_provider
|
|
22
|
+
_default_provider = provider
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_default_tier3_provider() -> Tier3Provider | None:
|
|
26
|
+
"""Return the registered default Tier 3 provider, or ``None`` if unset."""
|
|
27
|
+
return _default_provider
|