aiverify-moonshot 0.4.0__py3-none-any.whl
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.
- aiverify_moonshot-0.4.0.dist-info/METADATA +249 -0
- aiverify_moonshot-0.4.0.dist-info/RECORD +163 -0
- aiverify_moonshot-0.4.0.dist-info/WHEEL +4 -0
- aiverify_moonshot-0.4.0.dist-info/licenses/AUTHORS.md +5 -0
- aiverify_moonshot-0.4.0.dist-info/licenses/LICENSE.md +201 -0
- aiverify_moonshot-0.4.0.dist-info/licenses/NOTICES.md +3340 -0
- moonshot/__init__.py +0 -0
- moonshot/__main__.py +198 -0
- moonshot/api.py +155 -0
- moonshot/integrations/__init__.py +0 -0
- moonshot/integrations/cli/__init__.py +0 -0
- moonshot/integrations/cli/__main__.py +25 -0
- moonshot/integrations/cli/active_session_cfg.py +1 -0
- moonshot/integrations/cli/benchmark/__init__.py +0 -0
- moonshot/integrations/cli/benchmark/benchmark.py +186 -0
- moonshot/integrations/cli/benchmark/cookbook.py +545 -0
- moonshot/integrations/cli/benchmark/datasets.py +164 -0
- moonshot/integrations/cli/benchmark/metrics.py +141 -0
- moonshot/integrations/cli/benchmark/recipe.py +598 -0
- moonshot/integrations/cli/benchmark/result.py +216 -0
- moonshot/integrations/cli/benchmark/run.py +140 -0
- moonshot/integrations/cli/benchmark/runner.py +174 -0
- moonshot/integrations/cli/cli.py +64 -0
- moonshot/integrations/cli/common/__init__.py +0 -0
- moonshot/integrations/cli/common/common.py +72 -0
- moonshot/integrations/cli/common/connectors.py +325 -0
- moonshot/integrations/cli/common/display_helper.py +42 -0
- moonshot/integrations/cli/common/prompt_template.py +94 -0
- moonshot/integrations/cli/initialisation/__init__.py +0 -0
- moonshot/integrations/cli/initialisation/initialisation.py +14 -0
- moonshot/integrations/cli/redteam/__init__.py +0 -0
- moonshot/integrations/cli/redteam/attack_module.py +70 -0
- moonshot/integrations/cli/redteam/context_strategy.py +147 -0
- moonshot/integrations/cli/redteam/prompt_template.py +67 -0
- moonshot/integrations/cli/redteam/redteam.py +90 -0
- moonshot/integrations/cli/redteam/session.py +467 -0
- moonshot/integrations/web_api/.env.dev +7 -0
- moonshot/integrations/web_api/__init__.py +0 -0
- moonshot/integrations/web_api/__main__.py +56 -0
- moonshot/integrations/web_api/app.py +125 -0
- moonshot/integrations/web_api/container.py +146 -0
- moonshot/integrations/web_api/log/.gitkeep +0 -0
- moonshot/integrations/web_api/logging_conf.py +114 -0
- moonshot/integrations/web_api/routes/__init__.py +0 -0
- moonshot/integrations/web_api/routes/attack_modules.py +66 -0
- moonshot/integrations/web_api/routes/benchmark.py +116 -0
- moonshot/integrations/web_api/routes/benchmark_result.py +175 -0
- moonshot/integrations/web_api/routes/context_strategy.py +129 -0
- moonshot/integrations/web_api/routes/cookbook.py +225 -0
- moonshot/integrations/web_api/routes/dataset.py +120 -0
- moonshot/integrations/web_api/routes/endpoint.py +282 -0
- moonshot/integrations/web_api/routes/metric.py +78 -0
- moonshot/integrations/web_api/routes/prompt_template.py +128 -0
- moonshot/integrations/web_api/routes/recipe.py +219 -0
- moonshot/integrations/web_api/routes/redteam.py +609 -0
- moonshot/integrations/web_api/routes/runner.py +239 -0
- moonshot/integrations/web_api/schemas/__init__.py +0 -0
- moonshot/integrations/web_api/schemas/benchmark_runner_dto.py +13 -0
- moonshot/integrations/web_api/schemas/cookbook_create_dto.py +19 -0
- moonshot/integrations/web_api/schemas/cookbook_response_model.py +9 -0
- moonshot/integrations/web_api/schemas/dataset_response_dto.py +9 -0
- moonshot/integrations/web_api/schemas/endpoint_create_dto.py +21 -0
- moonshot/integrations/web_api/schemas/endpoint_response_model.py +11 -0
- moonshot/integrations/web_api/schemas/prompt_response_model.py +14 -0
- moonshot/integrations/web_api/schemas/prompt_template_response_model.py +10 -0
- moonshot/integrations/web_api/schemas/recipe_create_dto.py +32 -0
- moonshot/integrations/web_api/schemas/recipe_response_model.py +7 -0
- moonshot/integrations/web_api/schemas/session_create_dto.py +16 -0
- moonshot/integrations/web_api/schemas/session_prompt_dto.py +7 -0
- moonshot/integrations/web_api/schemas/session_response_model.py +38 -0
- moonshot/integrations/web_api/services/__init__.py +0 -0
- moonshot/integrations/web_api/services/attack_module_service.py +34 -0
- moonshot/integrations/web_api/services/auto_red_team_test_manager.py +86 -0
- moonshot/integrations/web_api/services/auto_red_team_test_state.py +57 -0
- moonshot/integrations/web_api/services/base_service.py +8 -0
- moonshot/integrations/web_api/services/benchmark_result_service.py +25 -0
- moonshot/integrations/web_api/services/benchmark_test_manager.py +106 -0
- moonshot/integrations/web_api/services/benchmark_test_state.py +56 -0
- moonshot/integrations/web_api/services/benchmarking_service.py +31 -0
- moonshot/integrations/web_api/services/context_strategy_service.py +22 -0
- moonshot/integrations/web_api/services/cookbook_service.py +194 -0
- moonshot/integrations/web_api/services/dataset_service.py +20 -0
- moonshot/integrations/web_api/services/endpoint_service.py +65 -0
- moonshot/integrations/web_api/services/metric_service.py +14 -0
- moonshot/integrations/web_api/services/prompt_template_service.py +39 -0
- moonshot/integrations/web_api/services/recipe_service.py +155 -0
- moonshot/integrations/web_api/services/runner_service.py +147 -0
- moonshot/integrations/web_api/services/session_service.py +350 -0
- moonshot/integrations/web_api/services/utils/exceptions_handler.py +41 -0
- moonshot/integrations/web_api/services/utils/results_formatter.py +47 -0
- moonshot/integrations/web_api/status_updater/interface/benchmark_progress_callback.py +14 -0
- moonshot/integrations/web_api/status_updater/interface/redteam_progress_callback.py +14 -0
- moonshot/integrations/web_api/status_updater/moonshot_ui_webhook.py +72 -0
- moonshot/integrations/web_api/types/types.py +99 -0
- moonshot/src/__init__.py +0 -0
- moonshot/src/api/__init__.py +0 -0
- moonshot/src/api/api_connector.py +58 -0
- moonshot/src/api/api_connector_endpoint.py +162 -0
- moonshot/src/api/api_context_strategy.py +57 -0
- moonshot/src/api/api_cookbook.py +160 -0
- moonshot/src/api/api_dataset.py +46 -0
- moonshot/src/api/api_environment_variables.py +17 -0
- moonshot/src/api/api_metrics.py +51 -0
- moonshot/src/api/api_prompt_template.py +43 -0
- moonshot/src/api/api_recipe.py +182 -0
- moonshot/src/api/api_red_teaming.py +59 -0
- moonshot/src/api/api_result.py +84 -0
- moonshot/src/api/api_run.py +74 -0
- moonshot/src/api/api_runner.py +132 -0
- moonshot/src/api/api_session.py +290 -0
- moonshot/src/configs/__init__.py +0 -0
- moonshot/src/configs/env_variables.py +187 -0
- moonshot/src/connectors/__init__.py +0 -0
- moonshot/src/connectors/connector.py +327 -0
- moonshot/src/connectors/connector_prompt_arguments.py +17 -0
- moonshot/src/connectors_endpoints/__init__.py +0 -0
- moonshot/src/connectors_endpoints/connector_endpoint.py +211 -0
- moonshot/src/connectors_endpoints/connector_endpoint_arguments.py +54 -0
- moonshot/src/cookbooks/__init__.py +0 -0
- moonshot/src/cookbooks/cookbook.py +225 -0
- moonshot/src/cookbooks/cookbook_arguments.py +34 -0
- moonshot/src/datasets/__init__.py +0 -0
- moonshot/src/datasets/dataset.py +255 -0
- moonshot/src/datasets/dataset_arguments.py +50 -0
- moonshot/src/metrics/__init__.py +0 -0
- moonshot/src/metrics/metric.py +192 -0
- moonshot/src/metrics/metric_interface.py +95 -0
- moonshot/src/prompt_templates/__init__.py +0 -0
- moonshot/src/prompt_templates/prompt_template.py +103 -0
- moonshot/src/recipes/__init__.py +0 -0
- moonshot/src/recipes/recipe.py +340 -0
- moonshot/src/recipes/recipe_arguments.py +111 -0
- moonshot/src/redteaming/__init__.py +0 -0
- moonshot/src/redteaming/attack/__init__.py +0 -0
- moonshot/src/redteaming/attack/attack_module.py +618 -0
- moonshot/src/redteaming/attack/attack_module_arguments.py +44 -0
- moonshot/src/redteaming/attack/context_strategy.py +131 -0
- moonshot/src/redteaming/context_strategy/__init__.py +0 -0
- moonshot/src/redteaming/context_strategy/context_strategy_interface.py +46 -0
- moonshot/src/redteaming/session/__init__.py +0 -0
- moonshot/src/redteaming/session/chat.py +209 -0
- moonshot/src/redteaming/session/red_teaming_progress.py +128 -0
- moonshot/src/redteaming/session/red_teaming_type.py +6 -0
- moonshot/src/redteaming/session/session.py +775 -0
- moonshot/src/results/__init__.py +0 -0
- moonshot/src/results/result.py +119 -0
- moonshot/src/results/result_arguments.py +44 -0
- moonshot/src/runners/__init__.py +0 -0
- moonshot/src/runners/runner.py +476 -0
- moonshot/src/runners/runner_arguments.py +46 -0
- moonshot/src/runners/runner_type.py +6 -0
- moonshot/src/runs/__init__.py +0 -0
- moonshot/src/runs/run.py +344 -0
- moonshot/src/runs/run_arguments.py +162 -0
- moonshot/src/runs/run_progress.py +145 -0
- moonshot/src/runs/run_status.py +10 -0
- moonshot/src/storage/__init__.py +0 -0
- moonshot/src/storage/db_interface.py +128 -0
- moonshot/src/storage/io_interface.py +31 -0
- moonshot/src/storage/storage.py +525 -0
- moonshot/src/utils/__init__.py +0 -0
- moonshot/src/utils/import_modules.py +96 -0
- moonshot/src/utils/timeit.py +25 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
from dependency_injector.wiring import Provide, inject
|
|
2
|
+
from fastapi import APIRouter, Depends, HTTPException
|
|
3
|
+
|
|
4
|
+
from ..container import Container
|
|
5
|
+
from ..services.runner_service import RunnerService
|
|
6
|
+
from ..services.utils.exceptions_handler import ServiceException
|
|
7
|
+
|
|
8
|
+
router = APIRouter(tags=["Runner"])
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@router.get("/api/v1/runners")
|
|
12
|
+
@inject
|
|
13
|
+
def get_all_runners(
|
|
14
|
+
runner_service: RunnerService = Depends(Provide[Container.runner_service]),
|
|
15
|
+
) -> list:
|
|
16
|
+
"""
|
|
17
|
+
Retrieve all runners from the database.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
runner_service (RunnerService): The service responsible for retrieving runners.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
list: A list of all runners.
|
|
24
|
+
|
|
25
|
+
Raises:
|
|
26
|
+
HTTPException: An error with status code 404 if no runners are found.
|
|
27
|
+
An error with status code 400 if there is a validation error.
|
|
28
|
+
An error with status code 500 for any other server-side error.
|
|
29
|
+
"""
|
|
30
|
+
try:
|
|
31
|
+
return runner_service.get_all_runner()
|
|
32
|
+
except ServiceException as e:
|
|
33
|
+
if e.error_code == "FileNotFound":
|
|
34
|
+
raise HTTPException(
|
|
35
|
+
status_code=404, detail=f"Failed to retrieve runners: {e.msg}"
|
|
36
|
+
)
|
|
37
|
+
elif e.error_code == "ValidationError":
|
|
38
|
+
raise HTTPException(
|
|
39
|
+
status_code=400, detail=f"Failed to retrieve runners: {e.msg}"
|
|
40
|
+
)
|
|
41
|
+
else:
|
|
42
|
+
raise HTTPException(
|
|
43
|
+
status_code=500, detail=f"Failed to retrieve runners: {e.msg}"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@router.get("/api/v1/runners/name")
|
|
48
|
+
@inject
|
|
49
|
+
def get_all_runner_name(
|
|
50
|
+
runner_service: RunnerService = Depends(Provide[Container.runner_service]),
|
|
51
|
+
) -> list:
|
|
52
|
+
"""
|
|
53
|
+
Retrieve all runner names from the database.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
runner_service (RunnerService): The service responsible for retrieving runner names.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
list: A list of all runner names.
|
|
60
|
+
|
|
61
|
+
Raises:
|
|
62
|
+
HTTPException: An error with status code 404 if no runner names are found.
|
|
63
|
+
An error with status code 400 if there is a validation error.
|
|
64
|
+
An error with status code 500 for any other server-side error.
|
|
65
|
+
"""
|
|
66
|
+
try:
|
|
67
|
+
return runner_service.get_all_runner_name()
|
|
68
|
+
except ServiceException as e:
|
|
69
|
+
if e.error_code == "FileNotFound":
|
|
70
|
+
raise HTTPException(
|
|
71
|
+
status_code=404, detail=f"Failed to retrieve runner names: {e.msg}"
|
|
72
|
+
)
|
|
73
|
+
elif e.error_code == "ValidationError":
|
|
74
|
+
raise HTTPException(
|
|
75
|
+
status_code=400, detail=f"Failed to retrieve runner names: {e.msg}"
|
|
76
|
+
)
|
|
77
|
+
else:
|
|
78
|
+
raise HTTPException(
|
|
79
|
+
status_code=500, detail=f"Failed to retrieve runner names: {e.msg}"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@router.get("/api/v1/runners/{runner_id}")
|
|
84
|
+
@inject
|
|
85
|
+
def get_runner_by_id(
|
|
86
|
+
runner_id: str,
|
|
87
|
+
runner_service: RunnerService = Depends(Provide[Container.runner_service]),
|
|
88
|
+
) -> dict:
|
|
89
|
+
"""
|
|
90
|
+
Retrieve a specific runner by their ID from the database.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
runner_id (str): The unique identifier of the runner to retrieve.
|
|
94
|
+
runner_service (RunnerService): The service responsible for retrieving the runner.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
dict: The runner information if found.
|
|
98
|
+
|
|
99
|
+
Raises:
|
|
100
|
+
HTTPException: An error with status code 404 if the runner is not found.
|
|
101
|
+
An error with status code 400 if there is a validation error.
|
|
102
|
+
An error with status code 500 for any other server-side error.
|
|
103
|
+
"""
|
|
104
|
+
try:
|
|
105
|
+
run = runner_service.get_runner_by_id(runner_id)
|
|
106
|
+
return run
|
|
107
|
+
except ServiceException as e:
|
|
108
|
+
if e.error_code == "FileNotFound":
|
|
109
|
+
raise HTTPException(
|
|
110
|
+
status_code=404, detail=f"Failed to retrieve runner: {e.msg}"
|
|
111
|
+
)
|
|
112
|
+
elif e.error_code == "ValidationError":
|
|
113
|
+
raise HTTPException(
|
|
114
|
+
status_code=400, detail=f"Failed to retrieve runner: {e.msg}"
|
|
115
|
+
)
|
|
116
|
+
else:
|
|
117
|
+
raise HTTPException(
|
|
118
|
+
status_code=500, detail=f"Failed to retrieve runner: {e.msg}"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@router.delete("/api/v1/runners/{runner_id}")
|
|
123
|
+
@inject
|
|
124
|
+
def delete_runner(
|
|
125
|
+
runner_id: str,
|
|
126
|
+
runner_service: RunnerService = Depends(Provide[Container.runner_service]),
|
|
127
|
+
) -> dict:
|
|
128
|
+
"""
|
|
129
|
+
Delete a specific runner by their ID from the database.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
runner_id (str): The unique identifier of the runner to delete.
|
|
133
|
+
runner_service (RunnerService): The service responsible for deleting the runner.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
dict: A message indicating the successful deletion of the runner.
|
|
137
|
+
|
|
138
|
+
Raises:
|
|
139
|
+
HTTPException: An error with status code 404 if the runner is not found.
|
|
140
|
+
An error with status code 400 if there is a validation error.
|
|
141
|
+
An error with status code 500 for any other server-side error.
|
|
142
|
+
"""
|
|
143
|
+
try:
|
|
144
|
+
runner_service.delete_run(runner_id)
|
|
145
|
+
return {"message": "Runner deleted successfully"}
|
|
146
|
+
except ServiceException as e:
|
|
147
|
+
if e.error_code == "FileNotFound":
|
|
148
|
+
raise HTTPException(
|
|
149
|
+
status_code=404, detail=f"Failed to delete runner: {e.msg}"
|
|
150
|
+
)
|
|
151
|
+
elif e.error_code == "ValidationError":
|
|
152
|
+
raise HTTPException(
|
|
153
|
+
status_code=400, detail=f"Failed to delete runner: {e.msg}"
|
|
154
|
+
)
|
|
155
|
+
else:
|
|
156
|
+
raise HTTPException(
|
|
157
|
+
status_code=500, detail=f"Failed to delete runner: {e.msg}"
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@router.get("/api/v1/runners/{runner_id}/runs/{run_id}")
|
|
162
|
+
@inject
|
|
163
|
+
def get_run_details_by_runner(
|
|
164
|
+
runner_id: str,
|
|
165
|
+
run_id: str,
|
|
166
|
+
runner_service: RunnerService = Depends(Provide[Container.runner_service]),
|
|
167
|
+
) -> dict:
|
|
168
|
+
"""
|
|
169
|
+
Retrieve the details of a specific run by a runner.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
runner_id (str): The unique identifier of the runner.
|
|
173
|
+
run_id (str): The unique identifier of the run.
|
|
174
|
+
runner_service (RunnerService): The service responsible for retrieving run details.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
dict: The details of the run.
|
|
178
|
+
|
|
179
|
+
Raises:
|
|
180
|
+
HTTPException: An error with status code 404 if the run details are not found.
|
|
181
|
+
An error with status code 400 if there is a validation error.
|
|
182
|
+
An error with status code 500 for any other server-side error.
|
|
183
|
+
"""
|
|
184
|
+
try:
|
|
185
|
+
return runner_service.get_run_details_by_runner(runner_id, run_id)
|
|
186
|
+
except ServiceException as e:
|
|
187
|
+
if e.error_code == "FileNotFound":
|
|
188
|
+
raise HTTPException(
|
|
189
|
+
status_code=404,
|
|
190
|
+
detail=f"Failed to get run details from runner: {e.msg}",
|
|
191
|
+
)
|
|
192
|
+
elif e.error_code == "ValidationError":
|
|
193
|
+
raise HTTPException(
|
|
194
|
+
status_code=400,
|
|
195
|
+
detail=f"Failed to get run details from runner: {e.msg}",
|
|
196
|
+
)
|
|
197
|
+
else:
|
|
198
|
+
raise HTTPException(
|
|
199
|
+
status_code=500,
|
|
200
|
+
detail=f"Failed to get run details from runner: {e.msg}",
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
@router.get("/api/v1/runners/{runner_id}/runs")
|
|
205
|
+
@inject
|
|
206
|
+
def get_runs_id_in_runner(
|
|
207
|
+
runner_id: str,
|
|
208
|
+
runner_service: RunnerService = Depends(Provide[Container.runner_service]),
|
|
209
|
+
) -> list[int]:
|
|
210
|
+
"""
|
|
211
|
+
Retrieve a list of run identifiers associated with a specific runner.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
runner_id (str): The unique identifier of the runner.
|
|
215
|
+
runner_service (RunnerService): The service responsible for retrieving the list of runs.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
List[str]: A list of run identifiers.
|
|
219
|
+
|
|
220
|
+
Raises:
|
|
221
|
+
HTTPException: An error with status code 404 if no runs are found for the runner.
|
|
222
|
+
An error with status code 400 if there is a validation error.
|
|
223
|
+
An error with status code 500 for any other server-side error.
|
|
224
|
+
"""
|
|
225
|
+
try:
|
|
226
|
+
return runner_service.get_runs_id_in_runner(runner_id)
|
|
227
|
+
except ServiceException as e:
|
|
228
|
+
if e.error_code == "FileNotFound":
|
|
229
|
+
raise HTTPException(
|
|
230
|
+
status_code=404, detail=f"Failed to get runs from runner: {e.msg}"
|
|
231
|
+
)
|
|
232
|
+
elif e.error_code == "ValidationError":
|
|
233
|
+
raise HTTPException(
|
|
234
|
+
status_code=400, detail=f"Failed to get runs from runner: {e.msg}"
|
|
235
|
+
)
|
|
236
|
+
else:
|
|
237
|
+
raise HTTPException(
|
|
238
|
+
status_code=500, detail=f"Failed to get runs from runner: {e.msg}"
|
|
239
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from pydantic import BaseModel, ConfigDict
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BenchmarkRunnerDTO(BaseModel):
|
|
5
|
+
model_config = ConfigDict(from_attributes=True)
|
|
6
|
+
run_name: str
|
|
7
|
+
description: str
|
|
8
|
+
endpoints: list[str]
|
|
9
|
+
inputs: list[str]
|
|
10
|
+
num_of_prompts: int
|
|
11
|
+
random_seed: int
|
|
12
|
+
system_prompt: str
|
|
13
|
+
runner_processing_module: str
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from moonshot.src.cookbooks.cookbook_arguments import (
|
|
4
|
+
CookbookArguments as CookbookPydanticModel,
|
|
5
|
+
)
|
|
6
|
+
from pydantic import Field
|
|
7
|
+
|
|
8
|
+
class CookbookCreateDTO(CookbookPydanticModel):
|
|
9
|
+
id: Optional[str] = None
|
|
10
|
+
name: str = Field(..., min_length=1)
|
|
11
|
+
description: Optional[str] = Field(default="", min_length=1)
|
|
12
|
+
recipes: list[str] = Field(..., min_length=1)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CookbookUpdateDTO(CookbookPydanticModel):
|
|
16
|
+
id: Optional[str] = None
|
|
17
|
+
name: Optional[str] = Field(default=None, min_length=1)
|
|
18
|
+
description: Optional[str] = Field(default=None, min_length=1)
|
|
19
|
+
recipes: Optional[list[str]] = Field(default=None, min_length=1)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from moonshot.src.connectors_endpoints.connector_endpoint_arguments import (
|
|
4
|
+
ConnectorEndpointArguments as ConnectorEndpointPydanticModel,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class EndpointCreateDTO(ConnectorEndpointPydanticModel):
|
|
9
|
+
id: Optional[str] = None
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class EndpointUpdateDTO(ConnectorEndpointPydanticModel):
|
|
13
|
+
id: Optional[str] = None
|
|
14
|
+
name: Optional[str] = None
|
|
15
|
+
connector_type: Optional[str] = None
|
|
16
|
+
uri: Optional[str] = None
|
|
17
|
+
token: Optional[str] = None
|
|
18
|
+
max_calls_per_second: Optional[int] = None
|
|
19
|
+
max_concurrency: Optional[int] = None
|
|
20
|
+
params: Optional[dict] = None
|
|
21
|
+
created_date: Optional[str] = None
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from moonshot.src.connectors_endpoints.connector_endpoint_arguments import (
|
|
2
|
+
ConnectorEndpointArguments as ConnectorEndpointPydanticModel,
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class EndpointDataModel(ConnectorEndpointPydanticModel):
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
def mask_token(self):
|
|
10
|
+
if self.token:
|
|
11
|
+
self.token = "*" * len(self.token)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from pydantic import BaseModel, RootModel
|
|
2
|
+
|
|
3
|
+
from ..schemas.session_response_model import ChatRecord
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PromptInfo(BaseModel):
|
|
8
|
+
current_runner_id: str
|
|
9
|
+
current_chats: dict[str, list[ChatRecord]]
|
|
10
|
+
current_batch_size: int
|
|
11
|
+
current_status: str
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
PromptResponseModel = RootModel[PromptInfo]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from moonshot.src.recipes.recipe_arguments import RecipeArguments as RecipePydanticModel
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
class RecipeCreateDTO(RecipePydanticModel):
|
|
8
|
+
id: Optional[str] = None
|
|
9
|
+
name: str = Field(..., min_length=1)
|
|
10
|
+
description: Optional[str] = Field(default="", min_length=1)
|
|
11
|
+
tags: Optional[list[str]] = None
|
|
12
|
+
categories: Optional[list[str]] = None
|
|
13
|
+
datasets: list[str] = Field(..., min_length=1)
|
|
14
|
+
metrics: list[str] = Field(..., min_length=1)
|
|
15
|
+
prompt_templates: Optional[list[str]] = None
|
|
16
|
+
attack_modules: Optional[list[str]] = None
|
|
17
|
+
grading_scale: Optional[dict[str, list[int]]] = None
|
|
18
|
+
stats: Optional[dict] = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class RecipeUpdateDTO(RecipePydanticModel):
|
|
22
|
+
id: Optional[str] = None
|
|
23
|
+
name: Optional[str] = None
|
|
24
|
+
description: Optional[str] = Field(default="", min_length=1)
|
|
25
|
+
tags: Optional[list[str]] = None
|
|
26
|
+
categories: Optional[list[str]] = None
|
|
27
|
+
datasets: Optional[list[str]] = None
|
|
28
|
+
prompt_templates: Optional[list[str]] = None
|
|
29
|
+
metrics: Optional[list[str]] = None
|
|
30
|
+
attack_modules: Optional[list[str]] = None
|
|
31
|
+
grading_scale: Optional[dict[str, list[int]]] = None
|
|
32
|
+
stats: Optional[dict] = None
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class SessionCreateDTO(BaseModel):
|
|
7
|
+
model_config = ConfigDict(from_attributes=True)
|
|
8
|
+
name: str = Field(min_length=3)
|
|
9
|
+
description: Optional[str] = Field(default="", max_length=1000)
|
|
10
|
+
endpoints: list[str] = Field(min_length=1)
|
|
11
|
+
context_strategy: str = ""
|
|
12
|
+
prompt_template: str = ""
|
|
13
|
+
attack_module: str = ""
|
|
14
|
+
metric: str = ""
|
|
15
|
+
system_prompt: str = ""
|
|
16
|
+
cs_num_of_prev_prompts: int = 5
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from typing import Dict, List, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ChatRecord(BaseModel):
|
|
7
|
+
conn_id: str
|
|
8
|
+
context_strategy: Optional[str]
|
|
9
|
+
prompt_template: Optional[str]
|
|
10
|
+
attack_module: Optional[str]
|
|
11
|
+
metric: Optional[str]
|
|
12
|
+
prompt: str
|
|
13
|
+
prepared_prompt: str
|
|
14
|
+
system_prompt: Optional[str]
|
|
15
|
+
predicted_result: str
|
|
16
|
+
duration: str
|
|
17
|
+
prompt_time: str
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SessionMetadataModel(BaseModel):
|
|
21
|
+
session_id: str = Field(min_length=1)
|
|
22
|
+
description: Optional[str] = ""
|
|
23
|
+
endpoints: List[str] = Field(min_length=1)
|
|
24
|
+
created_epoch: str
|
|
25
|
+
created_datetime: str = Field(min_length=1)
|
|
26
|
+
prompt_template: Optional[str]
|
|
27
|
+
context_strategy: Optional[str]
|
|
28
|
+
cs_num_of_prev_prompts: int | None = 5
|
|
29
|
+
attack_module: Optional[str]
|
|
30
|
+
metric: Optional[str]
|
|
31
|
+
system_prompt: Optional[str]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class SessionResponseModel(BaseModel):
|
|
35
|
+
session_name: str
|
|
36
|
+
session_description: str
|
|
37
|
+
session: SessionMetadataModel
|
|
38
|
+
chat_records: Optional[Dict[str, List[ChatRecord]]]
|
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from .... import api as moonshot_api
|
|
2
|
+
from .base_service import BaseService
|
|
3
|
+
from .utils.exceptions_handler import exception_handler
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AttackModuleService(BaseService):
|
|
7
|
+
@exception_handler
|
|
8
|
+
def get_all_attack_module(self) -> list[str]:
|
|
9
|
+
"""
|
|
10
|
+
Retrieves a list of all available attack modules.
|
|
11
|
+
|
|
12
|
+
This method wraps the `api_get_all_attack_modules` function from the moonshot API and returns
|
|
13
|
+
a list of attack module names.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
list[str]: A list of strings, each denoting the name of an attack module.
|
|
17
|
+
"""
|
|
18
|
+
attack_modules = moonshot_api.api_get_all_attack_modules()
|
|
19
|
+
return attack_modules
|
|
20
|
+
|
|
21
|
+
@exception_handler
|
|
22
|
+
def get_all_attack_module_metadata(self) -> list[dict]:
|
|
23
|
+
"""
|
|
24
|
+
Retrieves metadata for all available attack modules.
|
|
25
|
+
|
|
26
|
+
This method calls the `api_get_all_attack_module_metadata` function from the moonshot API. It collects
|
|
27
|
+
metadata for each attack module, which includes details such as the module's name, description, and
|
|
28
|
+
any other relevant information provided by the module's `get_metadata` method.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
list[dict]: A list of dictionaries, each containing metadata of an attack module.
|
|
32
|
+
"""
|
|
33
|
+
am_metadata = moonshot_api.api_get_all_attack_module_metadata()
|
|
34
|
+
return am_metadata
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import uuid
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from dependency_injector.wiring import inject
|
|
6
|
+
|
|
7
|
+
from moonshot.src.runners.runner import Runner
|
|
8
|
+
|
|
9
|
+
from ..services.auto_red_team_test_state import AutoRedTeamTestState
|
|
10
|
+
from ..services.base_service import BaseService
|
|
11
|
+
from ..services.runner_service import RunnerService
|
|
12
|
+
from ..status_updater.interface.redteam_progress_callback import (
|
|
13
|
+
InterfaceRedTeamProgressCallback,
|
|
14
|
+
)
|
|
15
|
+
from ..types.types import RedTeamTestProgress
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AutoRedTeamTestManager(BaseService):
|
|
19
|
+
@inject
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
auto_red_team_test_state: AutoRedTeamTestState,
|
|
23
|
+
progress_status_updater: InterfaceRedTeamProgressCallback,
|
|
24
|
+
runner_service: RunnerService,
|
|
25
|
+
) -> None:
|
|
26
|
+
"""
|
|
27
|
+
Initialize the SessionService with dependencies.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
progress_status_updater (InterfaceRedTeamProgressCallback): The callback interface for progress updates.
|
|
31
|
+
runner_service (RunnerService): The service for managing runners.
|
|
32
|
+
"""
|
|
33
|
+
self.auto_red_team_test_state = auto_red_team_test_state
|
|
34
|
+
self.progress_status_updater = progress_status_updater
|
|
35
|
+
self.runner_service = runner_service
|
|
36
|
+
super().__init__()
|
|
37
|
+
|
|
38
|
+
def generate_unique_task_id(self) -> str:
|
|
39
|
+
unique_id = str(uuid.uuid4())
|
|
40
|
+
return f"task_{unique_id}"
|
|
41
|
+
|
|
42
|
+
def add_task(
|
|
43
|
+
self, executor_id: str, task: asyncio.Task[Any], moonshot_runner: Runner
|
|
44
|
+
) -> None:
|
|
45
|
+
self.auto_red_team_test_state.add_task(executor_id, task, moonshot_runner)
|
|
46
|
+
|
|
47
|
+
def remove_task(self, executor_id: str) -> None:
|
|
48
|
+
self.auto_red_team_test_state.remove_task(executor_id)
|
|
49
|
+
|
|
50
|
+
async def cancel_task(self, executor_id: str) -> None:
|
|
51
|
+
await self.auto_red_team_test_state.cancel_task(executor_id)
|
|
52
|
+
|
|
53
|
+
def update_progress_status(self, updates: RedTeamTestProgress):
|
|
54
|
+
self.auto_red_team_test_state.update_progress_status(updates)
|
|
55
|
+
|
|
56
|
+
def on_task_completed(self, task: asyncio.Task[Any]) -> None:
|
|
57
|
+
self.logger.debug(f"Task {task.get_name()} has completed")
|
|
58
|
+
|
|
59
|
+
async def schedule_art_task(
|
|
60
|
+
self, art_args: dict, active_runner: Runner, batch_size: int
|
|
61
|
+
) -> str:
|
|
62
|
+
task_id = self.generate_unique_task_id()
|
|
63
|
+
|
|
64
|
+
auto_redteam_coroutine = self.send_art_prompt(
|
|
65
|
+
art_args, active_runner, batch_size
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
task = asyncio.create_task(auto_redteam_coroutine, name=task_id)
|
|
69
|
+
|
|
70
|
+
def on_executor_completion(task: asyncio.Task[Any]):
|
|
71
|
+
if task.exception():
|
|
72
|
+
self.logger.error(
|
|
73
|
+
f"Executor {task.get_name()} has failed - {task.exception()}"
|
|
74
|
+
)
|
|
75
|
+
else:
|
|
76
|
+
self.logger.debug(f"Executor {task.get_name()} has completed")
|
|
77
|
+
|
|
78
|
+
task.add_done_callback(on_executor_completion)
|
|
79
|
+
|
|
80
|
+
self.add_task(active_runner.id, task, active_runner)
|
|
81
|
+
return active_runner.id
|
|
82
|
+
|
|
83
|
+
async def send_art_prompt(self, art_args, active_runner: Runner, batch_size: int):
|
|
84
|
+
await active_runner.run_red_teaming(
|
|
85
|
+
{"attack_strategies": [art_args], "chat_batch_size": batch_size}
|
|
86
|
+
)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from typing import Any, TypedDict
|
|
3
|
+
|
|
4
|
+
from moonshot.integrations.web_api.services.base_service import BaseService
|
|
5
|
+
from moonshot.integrations.web_api.types.types import RedTeamTestProgress
|
|
6
|
+
from moonshot.src.runners.runner import Runner
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AutoRedTeamTaskInfo(TypedDict):
|
|
10
|
+
async_task: asyncio.Task[Any]
|
|
11
|
+
moonshot_runner: Runner
|
|
12
|
+
status: RedTeamTestProgress | None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AutoRedTeamTestState(BaseService):
|
|
16
|
+
state: dict[str, AutoRedTeamTaskInfo] = {}
|
|
17
|
+
|
|
18
|
+
def add_task(
|
|
19
|
+
self, id: str, task: asyncio.Task[Any], moonshot_runner: Runner
|
|
20
|
+
) -> None:
|
|
21
|
+
self.state[id] = {
|
|
22
|
+
"async_task": task,
|
|
23
|
+
"moonshot_runner": moonshot_runner,
|
|
24
|
+
"status": None,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
def remove_task(self, id: str) -> AutoRedTeamTaskInfo:
|
|
28
|
+
return self.state.pop(id)
|
|
29
|
+
|
|
30
|
+
async def cancel_task(self, id: str) -> None:
|
|
31
|
+
task_info = self.state[id]
|
|
32
|
+
if task_info and not task_info["async_task"].done():
|
|
33
|
+
if task_info["moonshot_runner"]:
|
|
34
|
+
await task_info["moonshot_runner"].cancel()
|
|
35
|
+
task_info["async_task"].cancel()
|
|
36
|
+
self.logger.debug(f"Task {id} has been cancelled")
|
|
37
|
+
else:
|
|
38
|
+
self.logger.debug(f"Task {id} is already completed or does not exist.")
|
|
39
|
+
|
|
40
|
+
def update_progress_status(self, updates: RedTeamTestProgress) -> None:
|
|
41
|
+
self.logger.debug(updates)
|
|
42
|
+
self.state[updates["current_runner_id"]]["status"] = updates
|
|
43
|
+
|
|
44
|
+
def get_state(self) -> dict[str, AutoRedTeamTaskInfo]:
|
|
45
|
+
return self.state
|
|
46
|
+
|
|
47
|
+
def get_progress_status(self, id: str) -> RedTeamTestProgress | None:
|
|
48
|
+
if id in self.state:
|
|
49
|
+
return self.state[id]["status"]
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
def get_all_progress_status(self) -> dict[str, RedTeamTestProgress]:
|
|
53
|
+
return {
|
|
54
|
+
id: task_info["status"]
|
|
55
|
+
for id, task_info in self.state.items()
|
|
56
|
+
if task_info["status"] is not None
|
|
57
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from .... import api as moonshot_api
|
|
2
|
+
from ..services.base_service import BaseService
|
|
3
|
+
from ..services.utils.exceptions_handler import exception_handler
|
|
4
|
+
from ..types.types import BenchmarkResult
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BenchmarkResultService(BaseService):
|
|
8
|
+
@exception_handler
|
|
9
|
+
def get_all_results(self) -> list[BenchmarkResult]:
|
|
10
|
+
results = moonshot_api.api_get_all_result()
|
|
11
|
+
return [BenchmarkResult(**result) for result in results]
|
|
12
|
+
|
|
13
|
+
@exception_handler
|
|
14
|
+
def get_all_result_name(self) -> list[str] | None:
|
|
15
|
+
results = moonshot_api.api_get_all_result_name()
|
|
16
|
+
return results
|
|
17
|
+
|
|
18
|
+
@exception_handler
|
|
19
|
+
def get_result_by_id(self, result_id: str) -> BenchmarkResult:
|
|
20
|
+
result = moonshot_api.api_read_result(result_id)
|
|
21
|
+
return BenchmarkResult(**result)
|
|
22
|
+
|
|
23
|
+
@exception_handler
|
|
24
|
+
def delete_result(self, result_id: str) -> None:
|
|
25
|
+
moonshot_api.api_delete_result(result_id)
|