Skip to content

Commit 5fa33f0

Browse files
committed
feat(add cost module):
1 parent 72f1f74 commit 5fa33f0

File tree

4 files changed

+109
-5
lines changed

4 files changed

+109
-5
lines changed

.dockerignore

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,45 @@
1-
.git/
1+
# Byte-compiled / optimized / DLL files
22
__pycache__/
3+
*.py[cod]
4+
5+
# Distribution / packaging
6+
build/
7+
dist/
8+
*.egg-info/
9+
10+
# Virtual environments
11+
12+
.venv/
13+
env/
14+
ENV/
15+
16+
# Installer logs
17+
pip-log.txt
18+
pip-delete-this-directory.txt
19+
20+
# Unit test / coverage reports
21+
htmlcov/
22+
.tox/
23+
.coverage
24+
.cache
25+
nosetests.xml
26+
coverage.xml
27+
28+
# PyInstaller
29+
*.spec
30+
31+
# macOS specific files
32+
.DS_Store
33+
34+
# Windows specific files
35+
Thumbs.db
36+
desktop.ini
37+
38+
# Tools and editors
39+
.idea/
40+
.vscode/
41+
cmder/
42+
43+
# Output directories
44+
Output/
45+
te/

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ RUN pip install --no-cache-dir -r requirements.txt
2121
# Runtime stage
2222
FROM python:3.11-slim
2323

24+
# Set environment variables
25+
ENV PYTHONDONTWRITEBYTECODE=1
26+
ENV PYTHONUNBUFFERED=1
27+
2428
WORKDIR /app
2529

2630
# Copy only the necessary files from the builder stage
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
def calculate_cost(tokens: int, model: str = "deepseek-chat") -> float:
2+
"""Calculate API cost based on token count and model.
3+
4+
Args:
5+
tokens (int): Number of tokens used
6+
model (str): Model name to calculate cost for
7+
8+
Returns:
9+
float: Cost in USD
10+
"""
11+
# API pricing as of 2024-03-01
12+
pricing = {
13+
"deepseek-chat": {
14+
"input": 0.0007 / 1000, # $0.70 per million input tokens
15+
"output": 0.0028 / 1000, # $2.80 per million output tokens
16+
},
17+
"gpt-4-turbo": {
18+
"input": 0.01 / 1000, # $10 per million input tokens
19+
"output": 0.03 / 1000, # $30 per million output tokens
20+
},
21+
"gpt-4": {
22+
"input": 0.03 / 1000, # $30 per million input tokens
23+
"output": 0.06 / 1000, # $60 per million output tokens
24+
},
25+
"gpt-3.5-turbo": {
26+
"input": 0.0015 / 1000, # $1.50 per million input tokens
27+
"output": 0.002 / 1000, # $2.00 per million output tokens
28+
},
29+
"claude-3-opus": {
30+
"input": 0.015 / 1000, # $15 per million input tokens
31+
"output": 0.075 / 1000, # $75 per million output tokens
32+
},
33+
"claude-3-sonnet": {
34+
"input": 0.003 / 1000, # $3 per million input tokens
35+
"output": 0.015 / 1000, # $15 per million output tokens
36+
},
37+
"claude-3-haiku": {
38+
"input": 0.00025 / 1000, # $0.25 per million input tokens
39+
"output": 0.00125 / 1000, # $1.25 per million output tokens
40+
},
41+
"mistral-large": {
42+
"input": 0.008 / 1000, # $8 per million input tokens
43+
"output": 0.024 / 1000, # $24 per million output tokens
44+
},
45+
"mixtral-8x7b": {
46+
"input": 0.002 / 1000, # $2 per million input tokens
47+
"output": 0.006 / 1000, # $6 per million output tokens
48+
},
49+
}
50+
51+
if model not in pricing:
52+
raise ValueError(f"Unknown model: {model}")
53+
54+
# For now, assume 1:1 input/output ratio
55+
input_cost = tokens * pricing[model]["input"]
56+
output_cost = tokens * pricing[model]["output"]
57+
58+
return round(input_cost + output_cost, 4)

agentic_security/probe_actor/fuzzer.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from agentic_security.http_spec import Modality
1212
from agentic_security.models.schemas import Scan, ScanResult
13+
from agentic_security.probe_actor.cost_module import calculate_cost
1314
from agentic_security.probe_actor.refusal import refusal_heuristic
1415
from agentic_security.probe_data import audio_generator, image_generator, msj_data
1516
from agentic_security.probe_data.data import prepare_prompts
@@ -38,8 +39,6 @@ def multi_modality_spec(llm_spec):
3839
return llm_spec
3940
case _:
4041
return llm_spec
41-
# case _:
42-
# raise NotImplementedError(f"Modality {llm_spec.modality} not supported yet")
4342

4443

4544
async def process_prompt(
@@ -143,7 +142,7 @@ async def perform_single_shot_scan(
143142
module_failures += 1
144143
failure_rate = module_failures / max(processed_prompts, 1)
145144
failure_rates.append(failure_rate)
146-
cost = round(tokens * 1.5 / 1000_000, 2)
145+
cost = calculate_cost(tokens)
147146

148147
yield ScanResult(
149148
module=module.dataset_name,
@@ -274,7 +273,7 @@ async def perform_many_shot_scan(
274273

275274
failure_rate = module_failures / max(processed_prompts, 1)
276275
failure_rates.append(failure_rate)
277-
cost = round(tokens * 1.5 / 1000_000, 2)
276+
cost = calculate_cost(tokens)
278277

279278
yield ScanResult(
280279
module=module.dataset_name,

0 commit comments

Comments
 (0)