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,47 @@
|
|
|
1
|
+
def transform_web_format(original_dict: dict[str, dict[str, list[dict[str, dict[str, float]]]]]) -> dict[str, dict[str, list[dict[str, list[dict[str, list[dict[str, float]]]]]]]]:
|
|
2
|
+
transformed = {"metadata": original_dict["metadata"], "results": {"cookbooks": []}}
|
|
3
|
+
|
|
4
|
+
for cookbook_name, cookbook_data in original_dict.items():
|
|
5
|
+
if cookbook_name == "metadata":
|
|
6
|
+
continue # Skip the metadata entry
|
|
7
|
+
|
|
8
|
+
cookbook_entry = {"id": cookbook_name, "recipes": []}
|
|
9
|
+
for recipe_name, recipe_data in cookbook_data.items():
|
|
10
|
+
recipe_entry = {"id": recipe_name, "models": []}
|
|
11
|
+
|
|
12
|
+
for model_data_str, model_data in recipe_data.items():
|
|
13
|
+
# Extract model, recipe, dataset, prompt_template from the string
|
|
14
|
+
model, _, dataset, prompt_template = eval(model_data_str)
|
|
15
|
+
|
|
16
|
+
model_entry = {
|
|
17
|
+
"id": model,
|
|
18
|
+
"datasets": [
|
|
19
|
+
{
|
|
20
|
+
"id": dataset,
|
|
21
|
+
"prompt_templates": [
|
|
22
|
+
{
|
|
23
|
+
"id": prompt_template,
|
|
24
|
+
"metrics": model_data["results"]
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# Check if the model already exists in the recipe_entry
|
|
32
|
+
existing_model = next((m for m in recipe_entry["models"] if m["id"] == model), None)
|
|
33
|
+
if existing_model:
|
|
34
|
+
# Check if the dataset already exists in the model
|
|
35
|
+
existing_dataset = next((d for d in existing_model["datasets"] if d["id"] == dataset), None)
|
|
36
|
+
if existing_dataset:
|
|
37
|
+
existing_dataset["prompt_templates"].append(model_entry["datasets"][0]["prompt_templates"][0])
|
|
38
|
+
else:
|
|
39
|
+
existing_model["datasets"].append(model_entry["datasets"][0])
|
|
40
|
+
else:
|
|
41
|
+
recipe_entry["models"].append(model_entry)
|
|
42
|
+
|
|
43
|
+
cookbook_entry["recipes"].append(recipe_entry)
|
|
44
|
+
|
|
45
|
+
transformed["results"]["cookbooks"].append(cookbook_entry)
|
|
46
|
+
|
|
47
|
+
return transformed
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from ...types.types import TestRunProgress
|
|
3
|
+
|
|
4
|
+
class InterfaceBenchmarkProgressCallback(ABC):
|
|
5
|
+
"""
|
|
6
|
+
The interface to implement for handling of benchmark progress updates from moonshot library
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
@abstractmethod
|
|
10
|
+
def on_progress_update(self, progress_data: TestRunProgress) -> None:
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from ...types.types import TestRunProgress
|
|
3
|
+
|
|
4
|
+
class InterfaceRedTeamProgressCallback(ABC):
|
|
5
|
+
"""
|
|
6
|
+
The interface to implement for handling of redteam progress updates from moonshot library
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
@abstractmethod
|
|
10
|
+
def on_art_progress_update(self, progress_data: TestRunProgress) -> None:
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
import requests
|
|
5
|
+
from dependency_injector.wiring import inject
|
|
6
|
+
from dotenv import dotenv_values
|
|
7
|
+
|
|
8
|
+
from ..services.auto_red_team_test_state import AutoRedTeamTestState
|
|
9
|
+
from ..services.benchmark_test_state import BenchmarkTestState
|
|
10
|
+
from ..types.types import RedTeamTestProgress, TestRunProgress
|
|
11
|
+
from .interface.benchmark_progress_callback import InterfaceBenchmarkProgressCallback
|
|
12
|
+
from .interface.redteam_progress_callback import InterfaceRedTeamProgressCallback
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class MoonshotUIWebhook(
|
|
16
|
+
InterfaceBenchmarkProgressCallback, InterfaceRedTeamProgressCallback
|
|
17
|
+
):
|
|
18
|
+
"""
|
|
19
|
+
Implementation of the benchmark progress callback.
|
|
20
|
+
This class is responsible for sending the progress data to the webhook exposed by moonshot-ui server.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
@inject
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
benchmark_test_state: BenchmarkTestState,
|
|
27
|
+
auto_red_team_test_state: AutoRedTeamTestState,
|
|
28
|
+
) -> None:
|
|
29
|
+
self.benchmark_test_state = benchmark_test_state
|
|
30
|
+
self.auto_red_team_test_state = auto_red_team_test_state
|
|
31
|
+
self.url = str(
|
|
32
|
+
dotenv_values().get(
|
|
33
|
+
"MOONSHOT_UI_CALLBACK_URL",
|
|
34
|
+
"http://localhost:3000/api/v1/benchmarks/status",
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
self.art_url = str(
|
|
38
|
+
dotenv_values().get(
|
|
39
|
+
"MOONSHOT_UI_ART_CALLBACK_URL",
|
|
40
|
+
"http://localhost:3000/api/v1/redteaming/status",
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
def on_progress_update(self, progress_data: TestRunProgress) -> None:
|
|
45
|
+
logger = logging.getLogger()
|
|
46
|
+
logger.debug(json.dumps(progress_data, indent=2))
|
|
47
|
+
self.benchmark_test_state.update_progress_status(progress_data)
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
response = requests.post(self.url, json=progress_data)
|
|
51
|
+
response.raise_for_status()
|
|
52
|
+
logger.log(level=logging.DEBUG, msg=response.json())
|
|
53
|
+
logger.log(
|
|
54
|
+
level=logging.INFO, msg="Progress data successfully sent to the server."
|
|
55
|
+
)
|
|
56
|
+
except requests.RequestException as e:
|
|
57
|
+
logger.critical(msg=f"Failed to send progress data: {e}")
|
|
58
|
+
|
|
59
|
+
def on_art_progress_update(self, progress_data: RedTeamTestProgress) -> None:
|
|
60
|
+
logger = logging.getLogger()
|
|
61
|
+
logger.debug(json.dumps(progress_data, indent=2))
|
|
62
|
+
self.auto_red_team_test_state.update_progress_status(progress_data)
|
|
63
|
+
print("Calling Auto Red Team Callback")
|
|
64
|
+
try:
|
|
65
|
+
response = requests.post(self.art_url, json=progress_data)
|
|
66
|
+
response.raise_for_status()
|
|
67
|
+
logger.log(level=logging.DEBUG, msg=response.json())
|
|
68
|
+
logger.log(
|
|
69
|
+
level=logging.INFO, msg="Progress data successfully sent to the server."
|
|
70
|
+
)
|
|
71
|
+
except requests.RequestException as e:
|
|
72
|
+
logger.critical(msg=f"Failed to send progress data: {e}")
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import Any, List, NotRequired
|
|
3
|
+
|
|
4
|
+
from typing_extensions import TypedDict
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PromptDetails(TypedDict):
|
|
8
|
+
chat_record_id: int
|
|
9
|
+
conn_id: str
|
|
10
|
+
context_strategy: str
|
|
11
|
+
prompt_template: str
|
|
12
|
+
prompt: str
|
|
13
|
+
prepared_prompt: str
|
|
14
|
+
predicted_result: str
|
|
15
|
+
duration: str
|
|
16
|
+
prompt_time: str
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class EndpointChatHistory(TypedDict):
|
|
20
|
+
chat_id: str
|
|
21
|
+
endpoint: str
|
|
22
|
+
chat_history: list[PromptDetails]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
SessionChats = list[EndpointChatHistory]
|
|
26
|
+
SessionChatsGroupedBySessionId = dict[str, list[PromptDetails]]
|
|
27
|
+
|
|
28
|
+
ExecutiResultItem = dict[str, float]
|
|
29
|
+
ExecutionResults = dict[str, list[ExecutiResultItem]]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class TestRunProgress(TypedDict):
|
|
33
|
+
current_runner_id: str
|
|
34
|
+
current_runner_name: str
|
|
35
|
+
current_runner_type: str
|
|
36
|
+
current_duration: int
|
|
37
|
+
current_status: str
|
|
38
|
+
current_cookbook_index: int
|
|
39
|
+
current_cookbook_name: str
|
|
40
|
+
current_cookbook_total: int
|
|
41
|
+
current_recipe_index: int
|
|
42
|
+
current_recipe_name: str
|
|
43
|
+
current_recipe_total: int
|
|
44
|
+
current_progress: int
|
|
45
|
+
current_error_messages: List[str]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class RedTeamTestProgress(TypedDict):
|
|
49
|
+
current_runner_id: str
|
|
50
|
+
current_am_id: str
|
|
51
|
+
current_pt_id: str
|
|
52
|
+
current_cs_id: str
|
|
53
|
+
current_chats: list[dict]
|
|
54
|
+
current_batch_size: str
|
|
55
|
+
current_status: str
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class UvicornLoggingConfig(TypedDict):
|
|
59
|
+
version: int
|
|
60
|
+
formatters: dict[str, dict[str, Any]]
|
|
61
|
+
handlers: dict[str, dict[str, Any]]
|
|
62
|
+
root: dict[str, dict[str, Any] | list[str]]
|
|
63
|
+
disable_existing_loggers: bool
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class UvicornRunArgs(TypedDict, total=False):
|
|
67
|
+
host: NotRequired[str]
|
|
68
|
+
port: NotRequired[int]
|
|
69
|
+
ssl_keyfile: NotRequired[str]
|
|
70
|
+
ssl_certfile: NotRequired[str]
|
|
71
|
+
log_config: NotRequired[UvicornLoggingConfig]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class BenchmarkCollectionType(Enum):
|
|
75
|
+
COOKBOOK = "cookbook"
|
|
76
|
+
RECIPE = "recipe"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class ResultMetadata(TypedDict):
|
|
80
|
+
id: str
|
|
81
|
+
name: str
|
|
82
|
+
start_time: str
|
|
83
|
+
end_time: str
|
|
84
|
+
duration: int
|
|
85
|
+
recipes: List[str]
|
|
86
|
+
cookbooks: List[str]
|
|
87
|
+
endpoints: List[str]
|
|
88
|
+
num_of_prompts: int
|
|
89
|
+
status: str
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class RequiredMetadata(TypedDict):
|
|
93
|
+
metadata: ResultMetadata
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class BenchmarkResult(TypedDict, RequiredMetadata, total=False):
|
|
97
|
+
# This indicates that any other keys should map to dictionaries, but this is not enforced by static type checkers.
|
|
98
|
+
# It serves more as documentation for developers.
|
|
99
|
+
additional_properties: dict[str, Any]
|
moonshot/src/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from pydantic import conlist, validate_call
|
|
2
|
+
|
|
3
|
+
from moonshot.src.connectors.connector import Connector
|
|
4
|
+
from moonshot.src.connectors_endpoints.connector_endpoint import ConnectorEndpoint
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# ------------------------------------------------------------------------------
|
|
8
|
+
# Connector APIs
|
|
9
|
+
# ------------------------------------------------------------------------------
|
|
10
|
+
@validate_call
|
|
11
|
+
def api_create_connector_from_endpoint(ep_id: str) -> Connector:
|
|
12
|
+
"""
|
|
13
|
+
Creates a connector based on the provided endpoint ID.
|
|
14
|
+
|
|
15
|
+
This function retrieves the endpoint arguments using the provided endpoint ID and then creates a connector
|
|
16
|
+
based on those arguments. It utilizes the ConnectorManager's read_endpoint method to fetch the endpoint
|
|
17
|
+
arguments and then calls the create_connector method to initialize and return the connector.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
ep_id (str): The ID of the endpoint for which to create a connector.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
Connector: An initialized Connector object.
|
|
24
|
+
"""
|
|
25
|
+
return Connector.create(ConnectorEndpoint.read(ep_id))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@validate_call
|
|
29
|
+
def api_create_connectors_from_endpoints(
|
|
30
|
+
ep_ids: conlist(str, min_length=1)
|
|
31
|
+
) -> list[Connector]:
|
|
32
|
+
"""
|
|
33
|
+
Creates connectors for multiple endpoints based on their IDs.
|
|
34
|
+
|
|
35
|
+
This function takes a list of endpoint IDs, retrieves the corresponding endpoint arguments for each ID,
|
|
36
|
+
and then creates a connector for each set of arguments. It utilizes the ConnectorEndpoint's read method
|
|
37
|
+
to fetch the endpoint arguments and then calls the Connector's create method to initialize the connectors.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
ep_ids (conlist(str, min_length=1)): A list of endpoint IDs for which to create connectors.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
list[Connector]: A list of initialized Connector objects.
|
|
44
|
+
"""
|
|
45
|
+
return [Connector.create(ConnectorEndpoint.read(ep_id)) for ep_id in ep_ids]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def api_get_all_connector_type() -> list[str]:
|
|
49
|
+
"""
|
|
50
|
+
Retrieves a list of all available connector types.
|
|
51
|
+
|
|
52
|
+
This function calls the ConnectorManager's get_available_connector_types method to retrieve a list of all available
|
|
53
|
+
connector types. It returns the list of connector types.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
list[str]: A list of connector types.
|
|
57
|
+
"""
|
|
58
|
+
return Connector.get_available_items()
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
from pydantic import validate_call
|
|
2
|
+
|
|
3
|
+
from moonshot.src.connectors_endpoints.connector_endpoint import ConnectorEndpoint
|
|
4
|
+
from moonshot.src.connectors_endpoints.connector_endpoint_arguments import (
|
|
5
|
+
ConnectorEndpointArguments,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# ------------------------------------------------------------------------------
|
|
10
|
+
# Connector Endpoint APIs
|
|
11
|
+
# ------------------------------------------------------------------------------
|
|
12
|
+
@validate_call
|
|
13
|
+
def api_create_endpoint(
|
|
14
|
+
name: str,
|
|
15
|
+
connector_type: str,
|
|
16
|
+
uri: str,
|
|
17
|
+
token: str,
|
|
18
|
+
max_calls_per_second: int,
|
|
19
|
+
max_concurrency: int,
|
|
20
|
+
params: dict,
|
|
21
|
+
) -> str:
|
|
22
|
+
"""
|
|
23
|
+
Creates a new connector endpoint.
|
|
24
|
+
|
|
25
|
+
This function creates a new connector endpoint with the specified parameters. It initializes
|
|
26
|
+
a ConnectorEndpointArguments instance and then uses the ConnectorEndpoint class to create
|
|
27
|
+
the endpoint.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
name (str): The name of the endpoint.
|
|
31
|
+
connector_type (str): The type of the connector.
|
|
32
|
+
uri (str): The URI for the connector.
|
|
33
|
+
token (str): The token for authentication with the connector.
|
|
34
|
+
max_calls_per_second (int): The maximum number of calls allowed per second.
|
|
35
|
+
max_concurrency (int): The maximum number of concurrent calls allowed.
|
|
36
|
+
params (dict): Additional parameters for the connector.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
str: The ID of the newly created connector endpoint.
|
|
40
|
+
"""
|
|
41
|
+
# Create a new connector endpoint arguments instance.
|
|
42
|
+
# We do not need to provide id and created_date.
|
|
43
|
+
# This is because during creation:
|
|
44
|
+
# 1. the id is slugify from the name and stored as id.
|
|
45
|
+
# 2. the created_date is based on the os file created date and time.
|
|
46
|
+
connector_endpoint_args = ConnectorEndpointArguments(
|
|
47
|
+
id="",
|
|
48
|
+
name=name,
|
|
49
|
+
connector_type=connector_type,
|
|
50
|
+
uri=uri,
|
|
51
|
+
token=token,
|
|
52
|
+
max_calls_per_second=max_calls_per_second,
|
|
53
|
+
max_concurrency=max_concurrency,
|
|
54
|
+
params=params,
|
|
55
|
+
created_date="",
|
|
56
|
+
)
|
|
57
|
+
return ConnectorEndpoint.create(connector_endpoint_args)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@validate_call
|
|
61
|
+
def api_read_endpoint(ep_id: str) -> dict:
|
|
62
|
+
"""
|
|
63
|
+
Reads an endpoint from the connector manager.
|
|
64
|
+
|
|
65
|
+
This function reads an endpoint from the connector manager using the provided endpoint ID.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
ep_id (str): The ID of the endpoint to read.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
dict: A dictionary containing the endpoint information.
|
|
72
|
+
"""
|
|
73
|
+
return ConnectorEndpoint.read(ep_id).to_dict()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@validate_call
|
|
77
|
+
def api_update_endpoint(ep_id: str, **kwargs) -> bool:
|
|
78
|
+
"""
|
|
79
|
+
Updates an existing endpoint with new values.
|
|
80
|
+
|
|
81
|
+
This function updates an existing endpoint in the connector manager using the provided endpoint ID and
|
|
82
|
+
keyword arguments.
|
|
83
|
+
|
|
84
|
+
Each keyword argument corresponds to an attribute of the endpoint that should be updated.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
ep_id (str): The ID of the endpoint to update.
|
|
88
|
+
**kwargs: Arbitrary keyword arguments representing the attributes to update.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
bool: True if the update was successful.
|
|
92
|
+
|
|
93
|
+
Raises:
|
|
94
|
+
RuntimeError: If the endpoint with the given ID does not exist or the update failed.
|
|
95
|
+
"""
|
|
96
|
+
# Check if the endpoint exists
|
|
97
|
+
try:
|
|
98
|
+
existing_endpoint = ConnectorEndpoint.read(ep_id)
|
|
99
|
+
except Exception:
|
|
100
|
+
raise RuntimeError(
|
|
101
|
+
f"[api_connector_endpoint]: Endpoint with ID '{ep_id}' does not exist"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# Update the fields of the existing endpoint with the provided kwargs
|
|
105
|
+
for key, value in kwargs.items():
|
|
106
|
+
if hasattr(existing_endpoint, key):
|
|
107
|
+
setattr(existing_endpoint, key, value)
|
|
108
|
+
|
|
109
|
+
# Perform pydantic check on the updated existing endpoint
|
|
110
|
+
ConnectorEndpointArguments.model_validate(existing_endpoint.to_dict())
|
|
111
|
+
|
|
112
|
+
# Update the endpoint
|
|
113
|
+
return ConnectorEndpoint.update(existing_endpoint)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@validate_call
|
|
117
|
+
def api_delete_endpoint(ep_id: str) -> bool:
|
|
118
|
+
"""
|
|
119
|
+
Deletes an endpoint from the connector manager.
|
|
120
|
+
|
|
121
|
+
This function deletes an endpoint from the connector manager using the provided endpoint ID.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
ep_id (str): The ID of the endpoint to delete.
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
bool: True if the deletion was successful.
|
|
128
|
+
|
|
129
|
+
Raises:
|
|
130
|
+
RuntimeError: If the endpoint with the given ID does not exist or the deletion failed.
|
|
131
|
+
"""
|
|
132
|
+
return ConnectorEndpoint.delete(ep_id)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def api_get_all_endpoint() -> list[dict]:
|
|
136
|
+
"""
|
|
137
|
+
Retrieves a list of all available endpoints.
|
|
138
|
+
|
|
139
|
+
This function calls the ConnectorManager's get_available_endpoints method to retrieve a list of all available
|
|
140
|
+
endpoints and their details. It then converts each ConnectorEndpointArguments object into a dictionary for easier
|
|
141
|
+
consumption by the caller.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
list[dict]: A list of dictionaries, each representing an endpoint's details.
|
|
145
|
+
"""
|
|
146
|
+
_, endpoints = ConnectorEndpoint.get_available_items()
|
|
147
|
+
return [endpoint.to_dict() for endpoint in endpoints]
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def api_get_all_endpoint_name() -> list[str]:
|
|
151
|
+
"""
|
|
152
|
+
Retrieves a list of all endpoint names.
|
|
153
|
+
|
|
154
|
+
This function calls the ConnectorManager's get_available_endpoints method to retrieve a list of all available
|
|
155
|
+
endpoint names. It extracts the names from the tuple returned by get_available_endpoints, which contains a list
|
|
156
|
+
of endpoint names and a list of ConnectorEndpointArguments objects.
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
list[str]: A list of endpoint names.
|
|
160
|
+
"""
|
|
161
|
+
endpoints_names, _ = ConnectorEndpoint.get_available_items()
|
|
162
|
+
return endpoints_names
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from pydantic import validate_call
|
|
2
|
+
|
|
3
|
+
from moonshot.src.redteaming.attack.context_strategy import ContextStrategy
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# ------------------------------------------------------------------------------
|
|
7
|
+
# Context Strategy APIs
|
|
8
|
+
# ------------------------------------------------------------------------------
|
|
9
|
+
def api_get_all_context_strategies() -> list[str]:
|
|
10
|
+
"""
|
|
11
|
+
Retrieves and returns the names of all context strategies currently available.
|
|
12
|
+
|
|
13
|
+
This API endpoint interfaces with the `ContextStrategy.get_all_context_strategy_names` method to fetch a list
|
|
14
|
+
of all context strategy names. It's designed for clients that need to know what context strategies are available for
|
|
15
|
+
use in sessions or other components of the system.
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
list[str]: A list of strings, each representing the name of a context strategy.
|
|
19
|
+
"""
|
|
20
|
+
return ContextStrategy.get_all_context_strategies()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@validate_call
|
|
24
|
+
def api_delete_context_strategy(cs_id: str) -> bool:
|
|
25
|
+
"""
|
|
26
|
+
Deletes a context strategy identified by its ID.
|
|
27
|
+
|
|
28
|
+
This API endpoint interfaces with the `ContextStrategy.delete` method to remove a context strategy from the system.
|
|
29
|
+
It is used to manage the available context strategies by allowing for their removal when they are no longer needed.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
cs_id (str): The unique identifier of the context strategy to be deleted.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
bool: True if the context strategy was successfully deleted.
|
|
36
|
+
|
|
37
|
+
Raises:
|
|
38
|
+
Exception: If the deletion process encounters an error.
|
|
39
|
+
"""
|
|
40
|
+
return ContextStrategy.delete(cs_id)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def api_get_all_context_strategy_metadata() -> list:
|
|
44
|
+
"""
|
|
45
|
+
Retrieves metadata for all context strategy modules.
|
|
46
|
+
|
|
47
|
+
This function retrieves the metadata for all available context strategies and
|
|
48
|
+
returns a list of metadata dictionaries.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
list: A list of attack module metadata.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
return [
|
|
55
|
+
ContextStrategy.load(context_strategy_name).get_metadata() # type: ignore ; ducktyping
|
|
56
|
+
for context_strategy_name in ContextStrategy.get_all_context_strategies()
|
|
57
|
+
]
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
from pydantic import conlist, validate_call
|
|
2
|
+
|
|
3
|
+
from moonshot.src.cookbooks.cookbook import Cookbook
|
|
4
|
+
from moonshot.src.cookbooks.cookbook_arguments import CookbookArguments
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# ------------------------------------------------------------------------------
|
|
8
|
+
# Cookbook APIs
|
|
9
|
+
# ------------------------------------------------------------------------------
|
|
10
|
+
@validate_call
|
|
11
|
+
def api_create_cookbook(name: str, description: str, recipes: list[str]) -> str:
|
|
12
|
+
"""
|
|
13
|
+
Creates a new cookbook.
|
|
14
|
+
|
|
15
|
+
This function takes the name, description, and recipes for a new cookbook as input. It then creates a new
|
|
16
|
+
CookbookArguments object with these details and an empty id. The id is left empty because it will be generated
|
|
17
|
+
from the name during the creation process. The function then calls the Cookbook's create_cookbook method to
|
|
18
|
+
create the new cookbook.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
name (str): The name of the new cookbook.
|
|
22
|
+
description (str): A brief description of the new cookbook.
|
|
23
|
+
recipes (list[str]): A list of recipes to be included in the new cookbook.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
str: The ID of the newly created cookbook.
|
|
27
|
+
"""
|
|
28
|
+
# Create a new cookbook
|
|
29
|
+
# We do not need to provide the id.
|
|
30
|
+
# This is because during creation:
|
|
31
|
+
# 1. the id is slugify from the name and stored as id.
|
|
32
|
+
cb_args = CookbookArguments(
|
|
33
|
+
id="",
|
|
34
|
+
name=name,
|
|
35
|
+
description=description,
|
|
36
|
+
recipes=recipes,
|
|
37
|
+
)
|
|
38
|
+
return Cookbook.create(cb_args)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@validate_call
|
|
42
|
+
def api_read_cookbook(cb_id: str) -> dict:
|
|
43
|
+
"""
|
|
44
|
+
Retrieves a cookbook based on the provided cookbook ID.
|
|
45
|
+
|
|
46
|
+
This function reads a cookbook using the `read_cookbook` method
|
|
47
|
+
of the `Cookbook` class, and converts the returned `Cookbook` object to a dictionary using its `to_dict` method.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
cb_id (str): A cookbook ID.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
dict: A dictionary representing a cookbook.
|
|
54
|
+
"""
|
|
55
|
+
return Cookbook.read(cb_id).to_dict()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@validate_call
|
|
59
|
+
def api_read_cookbooks(cb_ids: conlist(str, min_length=1)) -> list[dict]:
|
|
60
|
+
"""
|
|
61
|
+
Retrieves a list of cookbooks based on the provided list of cookbook IDs.
|
|
62
|
+
|
|
63
|
+
This function iterates over the list of provided cookbook IDs, reads each cookbook using the `read_cookbook` method
|
|
64
|
+
of the `Cookbook` class, and converts the returned `Cookbook` objects to dictionaries using their `to_dict` method.
|
|
65
|
+
It then returns a list of these dictionary representations.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
cb_ids (conlist(str, min_length=1)): A list of cookbook IDs.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
list[dict]: A list of dictionaries representing the cookbooks.
|
|
72
|
+
"""
|
|
73
|
+
return [Cookbook.read(cb_id).to_dict() for cb_id in cb_ids]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@validate_call
|
|
77
|
+
def api_update_cookbook(cb_id: str, **kwargs) -> bool:
|
|
78
|
+
"""
|
|
79
|
+
Updates the fields of an existing cookbook with the provided keyword arguments.
|
|
80
|
+
|
|
81
|
+
This function first checks if the cookbook with the given ID exists. If it does, it updates the fields
|
|
82
|
+
of the cookbook with the provided keyword arguments. If a field does not exist on the cookbook, it is ignored.
|
|
83
|
+
After updating the fields, it persists the changes to the cookbook.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
cb_id (str): The ID of the cookbook to update.
|
|
87
|
+
**kwargs: Arbitrary keyword arguments representing the fields to update and their new values.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
bool: True if the cookbook was successfully updated.
|
|
91
|
+
|
|
92
|
+
Raises:
|
|
93
|
+
Exception: If there's an error during the update process.
|
|
94
|
+
"""
|
|
95
|
+
# Check if the cookbook exists
|
|
96
|
+
try:
|
|
97
|
+
existing_cookbook = Cookbook.read(cb_id)
|
|
98
|
+
except Exception:
|
|
99
|
+
raise RuntimeError(f"Cookbook with ID '{cb_id}' does not exist")
|
|
100
|
+
|
|
101
|
+
# Update the fields of the existing cookbook with the provided kwargs
|
|
102
|
+
for key, value in kwargs.items():
|
|
103
|
+
if hasattr(existing_cookbook, key):
|
|
104
|
+
setattr(existing_cookbook, key, value)
|
|
105
|
+
|
|
106
|
+
# Perform pydantic check on the updated existing cookbook
|
|
107
|
+
CookbookArguments.model_validate(existing_cookbook.to_dict())
|
|
108
|
+
|
|
109
|
+
# Update the cookbook
|
|
110
|
+
return Cookbook.update(existing_cookbook)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@validate_call
|
|
114
|
+
def api_delete_cookbook(cb_id: str) -> bool:
|
|
115
|
+
"""
|
|
116
|
+
Deletes a cookbook based on the provided cookbook ID.
|
|
117
|
+
|
|
118
|
+
This function calls the `delete` method of the `Cookbook` class with the given cookbook ID. If the cookbook
|
|
119
|
+
is successfully deleted, the method returns True, otherwise it returns False.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
cb_id (str): The ID of the cookbook to delete.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
bool: True if the cookbook was successfully deleted.
|
|
126
|
+
|
|
127
|
+
Raises:
|
|
128
|
+
Exception: If the deletion process encounters an error.
|
|
129
|
+
"""
|
|
130
|
+
return Cookbook.delete(cb_id)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def api_get_all_cookbook() -> list[dict]:
|
|
134
|
+
"""
|
|
135
|
+
Retrieves all available cookbooks.
|
|
136
|
+
|
|
137
|
+
This function calls the `get_available_cookbooks` method of the `Cookbook` class, which returns a tuple
|
|
138
|
+
containing a list of cookbook IDs and a list of `CookbookArguments` objects. The function then returns a list
|
|
139
|
+
of dictionaries, each representing a cookbook.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
list[dict]: A list of dictionaries, each representing a cookbook.
|
|
143
|
+
"""
|
|
144
|
+
_, cookbooks = Cookbook.get_available_items()
|
|
145
|
+
return [cookbook.to_dict() for cookbook in cookbooks]
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def api_get_all_cookbook_name() -> list[str]:
|
|
149
|
+
"""
|
|
150
|
+
Retrieves the names of all available cookbooks.
|
|
151
|
+
|
|
152
|
+
This function calls the `get_available_cookbooks` method of the `Cookbook` class, which returns a tuple
|
|
153
|
+
containing a list of cookbook IDs and a list of `CookbookArguments` objects. The function then returns the
|
|
154
|
+
list of cookbook IDs, which are the names of the cookbooks.
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
list[str]: A list of cookbook names.
|
|
158
|
+
"""
|
|
159
|
+
cookbooks_names, _ = Cookbook.get_available_items()
|
|
160
|
+
return cookbooks_names
|