anticells 0.2.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.
- anticells-0.2.0/MANIFEST.in +11 -0
- anticells-0.2.0/PKG-INFO +329 -0
- anticells-0.2.0/README.md +299 -0
- anticells-0.2.0/pyproject.toml +65 -0
- anticells-0.2.0/setup.cfg +4 -0
- anticells-0.2.0/src/anticells/__init__.py +7 -0
- anticells-0.2.0/src/anticells/cli.py +30 -0
- anticells-0.2.0/src/anticells/gaslighter/__init__.py +83 -0
- anticells-0.2.0/src/anticells/gaslighter/cli.py +453 -0
- anticells-0.2.0/src/anticells/gaslighter/client.py +1093 -0
- anticells-0.2.0/src/anticells/gaslighter/config.py +14 -0
- anticells-0.2.0/src/anticells/gaslighter/exceptions.py +39 -0
- anticells-0.2.0/src/anticells/gaslighter/models.py +462 -0
- anticells-0.2.0/src/anticells/gaslighter/progress.py +389 -0
- anticells-0.2.0/src/anticells/gaslighter/py.typed +1 -0
- anticells-0.2.0/src/anticells/gaslighter/relay.py +224 -0
- anticells-0.2.0/src/anticells/gaslighter/trace.py +319 -0
- anticells-0.2.0/src/anticells/gaslighter/version.py +4 -0
- anticells-0.2.0/src/anticells.egg-info/PKG-INFO +329 -0
- anticells-0.2.0/src/anticells.egg-info/SOURCES.txt +22 -0
- anticells-0.2.0/src/anticells.egg-info/dependency_links.txt +1 -0
- anticells-0.2.0/src/anticells.egg-info/entry_points.txt +2 -0
- anticells-0.2.0/src/anticells.egg-info/requires.txt +8 -0
- anticells-0.2.0/src/anticells.egg-info/top_level.txt +1 -0
anticells-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: anticells
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Official Python SDK for ANTICELLS products.
|
|
5
|
+
Author: ANTICELLS
|
|
6
|
+
License-Expression: LicenseRef-Proprietary
|
|
7
|
+
Project-URL: Homepage, https://anticells.theantitech.com/
|
|
8
|
+
Project-URL: Documentation, https://anticells.theantitech.com/
|
|
9
|
+
Keywords: anticells,ai,api,gaslighter,red-team,sdk
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Requires-Dist: httpx>=0.26.0
|
|
24
|
+
Requires-Dist: pydantic<3,>=2.7.4
|
|
25
|
+
Requires-Dist: tqdm>=4.66.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
28
|
+
Requires-Dist: build>=1.2.1; extra == "dev"
|
|
29
|
+
Requires-Dist: twine>=5.1.0; extra == "dev"
|
|
30
|
+
|
|
31
|
+
# ANTICELLS Python SDK
|
|
32
|
+
|
|
33
|
+
Python SDK for ANTICELLS products. The Gaslighter product is available as a
|
|
34
|
+
namespace inside the package:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from anticells import gaslighter
|
|
38
|
+
|
|
39
|
+
client = gaslighter.Client.from_env()
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Customers normally provide only an API key.
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
From PyPI:
|
|
47
|
+
|
|
48
|
+
```powershell
|
|
49
|
+
python -m pip install anticells
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For local development from this repository:
|
|
53
|
+
|
|
54
|
+
```powershell
|
|
55
|
+
python -m pip install -e .\sdk
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
For maintainers building release artifacts:
|
|
59
|
+
|
|
60
|
+
```powershell
|
|
61
|
+
cd sdk
|
|
62
|
+
python -m pip install -U build twine
|
|
63
|
+
python -m build
|
|
64
|
+
python -m twine check dist/*
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This creates both a wheel and source distribution in `sdk/dist/`.
|
|
68
|
+
|
|
69
|
+
For a built local wheel:
|
|
70
|
+
|
|
71
|
+
```powershell
|
|
72
|
+
python -m pip install .\dist\anticells-0.2.0-py3-none-any.whl
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Environment
|
|
76
|
+
|
|
77
|
+
```powershell
|
|
78
|
+
$env:ANTICELLS_API_KEY = "glk_live_customer_key"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Optional auth header override:
|
|
82
|
+
|
|
83
|
+
```powershell
|
|
84
|
+
$env:ANTICELLS_API_KEY_HEADER = "X-API-Key"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
For `Authorization: Bearer <key>` instead:
|
|
88
|
+
|
|
89
|
+
```powershell
|
|
90
|
+
$env:ANTICELLS_API_KEY_HEADER = "Authorization"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Command Line
|
|
94
|
+
|
|
95
|
+
Check connectivity:
|
|
96
|
+
|
|
97
|
+
```powershell
|
|
98
|
+
anticells gaslighter health
|
|
99
|
+
anticells gaslighter personas
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Manage account API keys:
|
|
103
|
+
|
|
104
|
+
```powershell
|
|
105
|
+
anticells gaslighter keys list
|
|
106
|
+
anticells gaslighter keys create --name "Notebook key"
|
|
107
|
+
anticells gaslighter keys revoke "key_..."
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Register and inspect targets:
|
|
111
|
+
|
|
112
|
+
```powershell
|
|
113
|
+
anticells gaslighter targets list
|
|
114
|
+
anticells gaslighter targets get "target_..."
|
|
115
|
+
|
|
116
|
+
anticells gaslighter targets register `
|
|
117
|
+
--url "http://localhost:8080/api/v1/execute" `
|
|
118
|
+
--mode relay `
|
|
119
|
+
--name "Production assistant" `
|
|
120
|
+
--skip-manifest `
|
|
121
|
+
--input-field "message" `
|
|
122
|
+
--body-template '{"message":"__TARGET_INPUT__"}'
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Run the relay from the machine that can reach a private/local target:
|
|
126
|
+
|
|
127
|
+
```powershell
|
|
128
|
+
anticells gaslighter relay run `
|
|
129
|
+
--target "target_..." `
|
|
130
|
+
--url "http://127.0.0.1:8080/api/v1/execute" `
|
|
131
|
+
--target-credential "target_model_key_or_jwt" `
|
|
132
|
+
--target-auth-type bearer `
|
|
133
|
+
--target-auth-header "Authorization" `
|
|
134
|
+
--target-auth-prefix "Bearer" `
|
|
135
|
+
--input-field "message" `
|
|
136
|
+
--body-template '{"message":"__TARGET_INPUT__"}'
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Run one campaign:
|
|
140
|
+
|
|
141
|
+
```powershell
|
|
142
|
+
anticells gaslighter attacks run `
|
|
143
|
+
--target "target_..." `
|
|
144
|
+
--objective "Evaluate whether the target preserves approval boundaries." `
|
|
145
|
+
--persona "audit_interface"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Run a family sweep:
|
|
149
|
+
|
|
150
|
+
```powershell
|
|
151
|
+
anticells gaslighter sweeps run `
|
|
152
|
+
--target "target_..." `
|
|
153
|
+
--family "system_prompt_extraction" `
|
|
154
|
+
--family "tool_abuse" `
|
|
155
|
+
--prompts-per-family 2
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Quick Start
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from anticells import gaslighter
|
|
162
|
+
|
|
163
|
+
client = gaslighter.Client(api_key="glk_live_customer_key")
|
|
164
|
+
|
|
165
|
+
target = client.register_target(
|
|
166
|
+
url="http://target-service:8080/chat",
|
|
167
|
+
name="Staging assistant",
|
|
168
|
+
connection_mode="sdk_relay",
|
|
169
|
+
skip_manifest=True,
|
|
170
|
+
target_body_template={"message": "__TARGET_INPUT__"},
|
|
171
|
+
target_body_template_configured=True,
|
|
172
|
+
target_input_field="message",
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
relay_runner, relay_thread, relay_stop = gaslighter.start_target_relay_thread(
|
|
176
|
+
client,
|
|
177
|
+
target_id=target.id,
|
|
178
|
+
target_url="http://target-service:8080/chat",
|
|
179
|
+
body_template={"message": "__TARGET_INPUT__"},
|
|
180
|
+
body_template_configured=True,
|
|
181
|
+
input_field="message",
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
result = client.attack(
|
|
186
|
+
target_id=target.id,
|
|
187
|
+
objective="Evaluate whether the target preserves approval boundaries.",
|
|
188
|
+
persona="audit_interface",
|
|
189
|
+
verbose=True,
|
|
190
|
+
)
|
|
191
|
+
print(result.outcome)
|
|
192
|
+
print(result.judge_summary)
|
|
193
|
+
finally:
|
|
194
|
+
relay_stop.set()
|
|
195
|
+
relay_thread.join(timeout=5)
|
|
196
|
+
relay_runner.close()
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`objective`, `custom_objective`, and the API-native `bad_objective` are all
|
|
200
|
+
accepted. The SDK sends the API field as `bad_objective`.
|
|
201
|
+
|
|
202
|
+
## Python Key Management
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
from anticells import gaslighter
|
|
206
|
+
|
|
207
|
+
client = gaslighter.Client.from_env()
|
|
208
|
+
|
|
209
|
+
keys = client.list_api_keys()
|
|
210
|
+
created = client.create_api_key(name="Notebook key")
|
|
211
|
+
client.revoke_api_key(created["key"]["id"])
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Target Registration Options
|
|
215
|
+
|
|
216
|
+
`register_target` mirrors the ANTICELLS target registration contract:
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
from anticells import gaslighter
|
|
220
|
+
|
|
221
|
+
client = gaslighter.Client.from_env()
|
|
222
|
+
|
|
223
|
+
target = client.register_target(
|
|
224
|
+
url="https://target.example/chat",
|
|
225
|
+
name="Production assistant",
|
|
226
|
+
connection_mode="direct",
|
|
227
|
+
credential="target-side-secret",
|
|
228
|
+
auth={"type": "bearer", "header": "Authorization", "prefix": "Bearer"},
|
|
229
|
+
skip_manifest=True,
|
|
230
|
+
extra_payload={"tenant": "acme"},
|
|
231
|
+
target_body_template={"query": "__TARGET_INPUT__"},
|
|
232
|
+
target_body_template_configured=True,
|
|
233
|
+
target_input_field="query",
|
|
234
|
+
target_input_aliases=["message", "prompt"],
|
|
235
|
+
upload_endpoint="/upload",
|
|
236
|
+
tool_invocation_endpoint="/tools",
|
|
237
|
+
file_read_endpoint="/files/read",
|
|
238
|
+
upload_file_field="artifact",
|
|
239
|
+
upload_message_field="note",
|
|
240
|
+
upload_extra_fields={"workspace": "red-team"},
|
|
241
|
+
)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
For reusable configuration objects:
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
from anticells import gaslighter
|
|
248
|
+
|
|
249
|
+
target = client.register_target_config(
|
|
250
|
+
gaslighter.RegisterTarget(url="https://target.example/chat")
|
|
251
|
+
)
|
|
252
|
+
client.update_target_config(target.id, gaslighter.UpdateTarget(credential=None))
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Use `connection_mode="sdk_relay"` for private/local targets. In relay mode, the
|
|
256
|
+
SDK calls the target directly and the ANTICELLS service does not need direct
|
|
257
|
+
network access to it.
|
|
258
|
+
|
|
259
|
+
For bearer auth, put only the token/JWT in `credential`. Use
|
|
260
|
+
`{"type": "bearer", "header": "Authorization", "prefix": "Bearer"}` for
|
|
261
|
+
`Authorization: Bearer <token>`.
|
|
262
|
+
|
|
263
|
+
## Family Sweep
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
from anticells import gaslighter
|
|
267
|
+
|
|
268
|
+
batch = client.family_sweep(
|
|
269
|
+
target_id=target.id,
|
|
270
|
+
families=["system_prompt_extraction", "tool_abuse", "hallucination"],
|
|
271
|
+
prompts_per_family=2,
|
|
272
|
+
direct_phase_enabled=True,
|
|
273
|
+
continue_on_child_failure=True,
|
|
274
|
+
verbose=True,
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
print(batch.status)
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
For full personalization:
|
|
281
|
+
|
|
282
|
+
```python
|
|
283
|
+
started = client.start_family_sweep_config(
|
|
284
|
+
gaslighter.StartFamilySweep(
|
|
285
|
+
target_id=target.id,
|
|
286
|
+
persona="audit_interface",
|
|
287
|
+
objective_match_mode="specified_only",
|
|
288
|
+
stateful_delivery="full_history",
|
|
289
|
+
max_history_turns=10,
|
|
290
|
+
direct_phase_enabled=False,
|
|
291
|
+
prompts_per_family=5,
|
|
292
|
+
families=["system_prompt_extraction", "tool_abuse"],
|
|
293
|
+
allow_weak_preflight=True,
|
|
294
|
+
preflight_override_reason="Authorized audit",
|
|
295
|
+
continue_on_child_failure=False,
|
|
296
|
+
)
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
result = client.wait_for_batch(started.batch_id, verbose=True)
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
`families=["all"]`, `families=["*"]`, or an empty family list runs every family.
|
|
303
|
+
|
|
304
|
+
## Reports
|
|
305
|
+
|
|
306
|
+
```python
|
|
307
|
+
report_markdown = client.get_campaign_report(result.campaign_id, tier="growth")
|
|
308
|
+
saved_path = client.save_campaign_report(
|
|
309
|
+
result.campaign_id,
|
|
310
|
+
"reports/gaslighter-campaign.md",
|
|
311
|
+
tier="growth",
|
|
312
|
+
)
|
|
313
|
+
print(saved_path)
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
The CLI can save reports too:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
anticells gaslighter attacks run --target "$TARGET_ID" --objective "..." --trace --report-path reports/campaign.md
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Notes
|
|
323
|
+
|
|
324
|
+
- `verbose=None` auto-enables tqdm only in interactive terminals.
|
|
325
|
+
- `verbose=True` forces progress output.
|
|
326
|
+
- `verbose=False` is suitable for CI and pipeline logs.
|
|
327
|
+
- `X-API-Key: <key>` is the default API-key style for the ANTICELLS gateway.
|
|
328
|
+
- Use `api_key_header="Authorization"` if you need `Authorization: Bearer <key>`.
|
|
329
|
+
- Use the public ANTICELLS API URL for packaged customer builds.
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# ANTICELLS Python SDK
|
|
2
|
+
|
|
3
|
+
Python SDK for ANTICELLS products. The Gaslighter product is available as a
|
|
4
|
+
namespace inside the package:
|
|
5
|
+
|
|
6
|
+
```python
|
|
7
|
+
from anticells import gaslighter
|
|
8
|
+
|
|
9
|
+
client = gaslighter.Client.from_env()
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Customers normally provide only an API key.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
From PyPI:
|
|
17
|
+
|
|
18
|
+
```powershell
|
|
19
|
+
python -m pip install anticells
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
For local development from this repository:
|
|
23
|
+
|
|
24
|
+
```powershell
|
|
25
|
+
python -m pip install -e .\sdk
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
For maintainers building release artifacts:
|
|
29
|
+
|
|
30
|
+
```powershell
|
|
31
|
+
cd sdk
|
|
32
|
+
python -m pip install -U build twine
|
|
33
|
+
python -m build
|
|
34
|
+
python -m twine check dist/*
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This creates both a wheel and source distribution in `sdk/dist/`.
|
|
38
|
+
|
|
39
|
+
For a built local wheel:
|
|
40
|
+
|
|
41
|
+
```powershell
|
|
42
|
+
python -m pip install .\dist\anticells-0.2.0-py3-none-any.whl
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Environment
|
|
46
|
+
|
|
47
|
+
```powershell
|
|
48
|
+
$env:ANTICELLS_API_KEY = "glk_live_customer_key"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Optional auth header override:
|
|
52
|
+
|
|
53
|
+
```powershell
|
|
54
|
+
$env:ANTICELLS_API_KEY_HEADER = "X-API-Key"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For `Authorization: Bearer <key>` instead:
|
|
58
|
+
|
|
59
|
+
```powershell
|
|
60
|
+
$env:ANTICELLS_API_KEY_HEADER = "Authorization"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Command Line
|
|
64
|
+
|
|
65
|
+
Check connectivity:
|
|
66
|
+
|
|
67
|
+
```powershell
|
|
68
|
+
anticells gaslighter health
|
|
69
|
+
anticells gaslighter personas
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Manage account API keys:
|
|
73
|
+
|
|
74
|
+
```powershell
|
|
75
|
+
anticells gaslighter keys list
|
|
76
|
+
anticells gaslighter keys create --name "Notebook key"
|
|
77
|
+
anticells gaslighter keys revoke "key_..."
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Register and inspect targets:
|
|
81
|
+
|
|
82
|
+
```powershell
|
|
83
|
+
anticells gaslighter targets list
|
|
84
|
+
anticells gaslighter targets get "target_..."
|
|
85
|
+
|
|
86
|
+
anticells gaslighter targets register `
|
|
87
|
+
--url "http://localhost:8080/api/v1/execute" `
|
|
88
|
+
--mode relay `
|
|
89
|
+
--name "Production assistant" `
|
|
90
|
+
--skip-manifest `
|
|
91
|
+
--input-field "message" `
|
|
92
|
+
--body-template '{"message":"__TARGET_INPUT__"}'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Run the relay from the machine that can reach a private/local target:
|
|
96
|
+
|
|
97
|
+
```powershell
|
|
98
|
+
anticells gaslighter relay run `
|
|
99
|
+
--target "target_..." `
|
|
100
|
+
--url "http://127.0.0.1:8080/api/v1/execute" `
|
|
101
|
+
--target-credential "target_model_key_or_jwt" `
|
|
102
|
+
--target-auth-type bearer `
|
|
103
|
+
--target-auth-header "Authorization" `
|
|
104
|
+
--target-auth-prefix "Bearer" `
|
|
105
|
+
--input-field "message" `
|
|
106
|
+
--body-template '{"message":"__TARGET_INPUT__"}'
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Run one campaign:
|
|
110
|
+
|
|
111
|
+
```powershell
|
|
112
|
+
anticells gaslighter attacks run `
|
|
113
|
+
--target "target_..." `
|
|
114
|
+
--objective "Evaluate whether the target preserves approval boundaries." `
|
|
115
|
+
--persona "audit_interface"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Run a family sweep:
|
|
119
|
+
|
|
120
|
+
```powershell
|
|
121
|
+
anticells gaslighter sweeps run `
|
|
122
|
+
--target "target_..." `
|
|
123
|
+
--family "system_prompt_extraction" `
|
|
124
|
+
--family "tool_abuse" `
|
|
125
|
+
--prompts-per-family 2
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Quick Start
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from anticells import gaslighter
|
|
132
|
+
|
|
133
|
+
client = gaslighter.Client(api_key="glk_live_customer_key")
|
|
134
|
+
|
|
135
|
+
target = client.register_target(
|
|
136
|
+
url="http://target-service:8080/chat",
|
|
137
|
+
name="Staging assistant",
|
|
138
|
+
connection_mode="sdk_relay",
|
|
139
|
+
skip_manifest=True,
|
|
140
|
+
target_body_template={"message": "__TARGET_INPUT__"},
|
|
141
|
+
target_body_template_configured=True,
|
|
142
|
+
target_input_field="message",
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
relay_runner, relay_thread, relay_stop = gaslighter.start_target_relay_thread(
|
|
146
|
+
client,
|
|
147
|
+
target_id=target.id,
|
|
148
|
+
target_url="http://target-service:8080/chat",
|
|
149
|
+
body_template={"message": "__TARGET_INPUT__"},
|
|
150
|
+
body_template_configured=True,
|
|
151
|
+
input_field="message",
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
result = client.attack(
|
|
156
|
+
target_id=target.id,
|
|
157
|
+
objective="Evaluate whether the target preserves approval boundaries.",
|
|
158
|
+
persona="audit_interface",
|
|
159
|
+
verbose=True,
|
|
160
|
+
)
|
|
161
|
+
print(result.outcome)
|
|
162
|
+
print(result.judge_summary)
|
|
163
|
+
finally:
|
|
164
|
+
relay_stop.set()
|
|
165
|
+
relay_thread.join(timeout=5)
|
|
166
|
+
relay_runner.close()
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`objective`, `custom_objective`, and the API-native `bad_objective` are all
|
|
170
|
+
accepted. The SDK sends the API field as `bad_objective`.
|
|
171
|
+
|
|
172
|
+
## Python Key Management
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from anticells import gaslighter
|
|
176
|
+
|
|
177
|
+
client = gaslighter.Client.from_env()
|
|
178
|
+
|
|
179
|
+
keys = client.list_api_keys()
|
|
180
|
+
created = client.create_api_key(name="Notebook key")
|
|
181
|
+
client.revoke_api_key(created["key"]["id"])
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Target Registration Options
|
|
185
|
+
|
|
186
|
+
`register_target` mirrors the ANTICELLS target registration contract:
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from anticells import gaslighter
|
|
190
|
+
|
|
191
|
+
client = gaslighter.Client.from_env()
|
|
192
|
+
|
|
193
|
+
target = client.register_target(
|
|
194
|
+
url="https://target.example/chat",
|
|
195
|
+
name="Production assistant",
|
|
196
|
+
connection_mode="direct",
|
|
197
|
+
credential="target-side-secret",
|
|
198
|
+
auth={"type": "bearer", "header": "Authorization", "prefix": "Bearer"},
|
|
199
|
+
skip_manifest=True,
|
|
200
|
+
extra_payload={"tenant": "acme"},
|
|
201
|
+
target_body_template={"query": "__TARGET_INPUT__"},
|
|
202
|
+
target_body_template_configured=True,
|
|
203
|
+
target_input_field="query",
|
|
204
|
+
target_input_aliases=["message", "prompt"],
|
|
205
|
+
upload_endpoint="/upload",
|
|
206
|
+
tool_invocation_endpoint="/tools",
|
|
207
|
+
file_read_endpoint="/files/read",
|
|
208
|
+
upload_file_field="artifact",
|
|
209
|
+
upload_message_field="note",
|
|
210
|
+
upload_extra_fields={"workspace": "red-team"},
|
|
211
|
+
)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
For reusable configuration objects:
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
from anticells import gaslighter
|
|
218
|
+
|
|
219
|
+
target = client.register_target_config(
|
|
220
|
+
gaslighter.RegisterTarget(url="https://target.example/chat")
|
|
221
|
+
)
|
|
222
|
+
client.update_target_config(target.id, gaslighter.UpdateTarget(credential=None))
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Use `connection_mode="sdk_relay"` for private/local targets. In relay mode, the
|
|
226
|
+
SDK calls the target directly and the ANTICELLS service does not need direct
|
|
227
|
+
network access to it.
|
|
228
|
+
|
|
229
|
+
For bearer auth, put only the token/JWT in `credential`. Use
|
|
230
|
+
`{"type": "bearer", "header": "Authorization", "prefix": "Bearer"}` for
|
|
231
|
+
`Authorization: Bearer <token>`.
|
|
232
|
+
|
|
233
|
+
## Family Sweep
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
from anticells import gaslighter
|
|
237
|
+
|
|
238
|
+
batch = client.family_sweep(
|
|
239
|
+
target_id=target.id,
|
|
240
|
+
families=["system_prompt_extraction", "tool_abuse", "hallucination"],
|
|
241
|
+
prompts_per_family=2,
|
|
242
|
+
direct_phase_enabled=True,
|
|
243
|
+
continue_on_child_failure=True,
|
|
244
|
+
verbose=True,
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
print(batch.status)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
For full personalization:
|
|
251
|
+
|
|
252
|
+
```python
|
|
253
|
+
started = client.start_family_sweep_config(
|
|
254
|
+
gaslighter.StartFamilySweep(
|
|
255
|
+
target_id=target.id,
|
|
256
|
+
persona="audit_interface",
|
|
257
|
+
objective_match_mode="specified_only",
|
|
258
|
+
stateful_delivery="full_history",
|
|
259
|
+
max_history_turns=10,
|
|
260
|
+
direct_phase_enabled=False,
|
|
261
|
+
prompts_per_family=5,
|
|
262
|
+
families=["system_prompt_extraction", "tool_abuse"],
|
|
263
|
+
allow_weak_preflight=True,
|
|
264
|
+
preflight_override_reason="Authorized audit",
|
|
265
|
+
continue_on_child_failure=False,
|
|
266
|
+
)
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
result = client.wait_for_batch(started.batch_id, verbose=True)
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`families=["all"]`, `families=["*"]`, or an empty family list runs every family.
|
|
273
|
+
|
|
274
|
+
## Reports
|
|
275
|
+
|
|
276
|
+
```python
|
|
277
|
+
report_markdown = client.get_campaign_report(result.campaign_id, tier="growth")
|
|
278
|
+
saved_path = client.save_campaign_report(
|
|
279
|
+
result.campaign_id,
|
|
280
|
+
"reports/gaslighter-campaign.md",
|
|
281
|
+
tier="growth",
|
|
282
|
+
)
|
|
283
|
+
print(saved_path)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
The CLI can save reports too:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
anticells gaslighter attacks run --target "$TARGET_ID" --objective "..." --trace --report-path reports/campaign.md
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Notes
|
|
293
|
+
|
|
294
|
+
- `verbose=None` auto-enables tqdm only in interactive terminals.
|
|
295
|
+
- `verbose=True` forces progress output.
|
|
296
|
+
- `verbose=False` is suitable for CI and pipeline logs.
|
|
297
|
+
- `X-API-Key: <key>` is the default API-key style for the ANTICELLS gateway.
|
|
298
|
+
- Use `api_key_header="Authorization"` if you need `Authorization: Bearer <key>`.
|
|
299
|
+
- Use the public ANTICELLS API URL for packaged customer builds.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "wheel", "packaging>=24.2"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "anticells"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Official Python SDK for ANTICELLS products."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "LicenseRef-Proprietary"
|
|
12
|
+
license-files = []
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "ANTICELLS" }
|
|
15
|
+
]
|
|
16
|
+
keywords = [
|
|
17
|
+
"anticells",
|
|
18
|
+
"ai",
|
|
19
|
+
"api",
|
|
20
|
+
"gaslighter",
|
|
21
|
+
"red-team",
|
|
22
|
+
"sdk",
|
|
23
|
+
]
|
|
24
|
+
classifiers = [
|
|
25
|
+
"Development Status :: 4 - Beta",
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"Operating System :: OS Independent",
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
29
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
30
|
+
"Programming Language :: Python :: 3.9",
|
|
31
|
+
"Programming Language :: Python :: 3.10",
|
|
32
|
+
"Programming Language :: Python :: 3.11",
|
|
33
|
+
"Programming Language :: Python :: 3.12",
|
|
34
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
35
|
+
"Typing :: Typed",
|
|
36
|
+
]
|
|
37
|
+
dependencies = [
|
|
38
|
+
"httpx>=0.26.0",
|
|
39
|
+
"pydantic>=2.7.4,<3",
|
|
40
|
+
"tqdm>=4.66.0",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.scripts]
|
|
44
|
+
anticells = "anticells.cli:main"
|
|
45
|
+
|
|
46
|
+
[project.urls]
|
|
47
|
+
Homepage = "https://anticells.theantitech.com/"
|
|
48
|
+
Documentation = "https://anticells.theantitech.com/"
|
|
49
|
+
|
|
50
|
+
[project.optional-dependencies]
|
|
51
|
+
dev = [
|
|
52
|
+
"pytest>=8.0.0",
|
|
53
|
+
"build>=1.2.1",
|
|
54
|
+
"twine>=5.1.0",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
[tool.setuptools]
|
|
58
|
+
package-dir = { "" = "src" }
|
|
59
|
+
|
|
60
|
+
[tool.setuptools.packages.find]
|
|
61
|
+
where = ["src"]
|
|
62
|
+
include = ["anticells*"]
|
|
63
|
+
|
|
64
|
+
[tool.setuptools.package-data]
|
|
65
|
+
"anticells.gaslighter" = ["py.typed"]
|