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.
Files changed (163) hide show
  1. aiverify_moonshot-0.4.0.dist-info/METADATA +249 -0
  2. aiverify_moonshot-0.4.0.dist-info/RECORD +163 -0
  3. aiverify_moonshot-0.4.0.dist-info/WHEEL +4 -0
  4. aiverify_moonshot-0.4.0.dist-info/licenses/AUTHORS.md +5 -0
  5. aiverify_moonshot-0.4.0.dist-info/licenses/LICENSE.md +201 -0
  6. aiverify_moonshot-0.4.0.dist-info/licenses/NOTICES.md +3340 -0
  7. moonshot/__init__.py +0 -0
  8. moonshot/__main__.py +198 -0
  9. moonshot/api.py +155 -0
  10. moonshot/integrations/__init__.py +0 -0
  11. moonshot/integrations/cli/__init__.py +0 -0
  12. moonshot/integrations/cli/__main__.py +25 -0
  13. moonshot/integrations/cli/active_session_cfg.py +1 -0
  14. moonshot/integrations/cli/benchmark/__init__.py +0 -0
  15. moonshot/integrations/cli/benchmark/benchmark.py +186 -0
  16. moonshot/integrations/cli/benchmark/cookbook.py +545 -0
  17. moonshot/integrations/cli/benchmark/datasets.py +164 -0
  18. moonshot/integrations/cli/benchmark/metrics.py +141 -0
  19. moonshot/integrations/cli/benchmark/recipe.py +598 -0
  20. moonshot/integrations/cli/benchmark/result.py +216 -0
  21. moonshot/integrations/cli/benchmark/run.py +140 -0
  22. moonshot/integrations/cli/benchmark/runner.py +174 -0
  23. moonshot/integrations/cli/cli.py +64 -0
  24. moonshot/integrations/cli/common/__init__.py +0 -0
  25. moonshot/integrations/cli/common/common.py +72 -0
  26. moonshot/integrations/cli/common/connectors.py +325 -0
  27. moonshot/integrations/cli/common/display_helper.py +42 -0
  28. moonshot/integrations/cli/common/prompt_template.py +94 -0
  29. moonshot/integrations/cli/initialisation/__init__.py +0 -0
  30. moonshot/integrations/cli/initialisation/initialisation.py +14 -0
  31. moonshot/integrations/cli/redteam/__init__.py +0 -0
  32. moonshot/integrations/cli/redteam/attack_module.py +70 -0
  33. moonshot/integrations/cli/redteam/context_strategy.py +147 -0
  34. moonshot/integrations/cli/redteam/prompt_template.py +67 -0
  35. moonshot/integrations/cli/redteam/redteam.py +90 -0
  36. moonshot/integrations/cli/redteam/session.py +467 -0
  37. moonshot/integrations/web_api/.env.dev +7 -0
  38. moonshot/integrations/web_api/__init__.py +0 -0
  39. moonshot/integrations/web_api/__main__.py +56 -0
  40. moonshot/integrations/web_api/app.py +125 -0
  41. moonshot/integrations/web_api/container.py +146 -0
  42. moonshot/integrations/web_api/log/.gitkeep +0 -0
  43. moonshot/integrations/web_api/logging_conf.py +114 -0
  44. moonshot/integrations/web_api/routes/__init__.py +0 -0
  45. moonshot/integrations/web_api/routes/attack_modules.py +66 -0
  46. moonshot/integrations/web_api/routes/benchmark.py +116 -0
  47. moonshot/integrations/web_api/routes/benchmark_result.py +175 -0
  48. moonshot/integrations/web_api/routes/context_strategy.py +129 -0
  49. moonshot/integrations/web_api/routes/cookbook.py +225 -0
  50. moonshot/integrations/web_api/routes/dataset.py +120 -0
  51. moonshot/integrations/web_api/routes/endpoint.py +282 -0
  52. moonshot/integrations/web_api/routes/metric.py +78 -0
  53. moonshot/integrations/web_api/routes/prompt_template.py +128 -0
  54. moonshot/integrations/web_api/routes/recipe.py +219 -0
  55. moonshot/integrations/web_api/routes/redteam.py +609 -0
  56. moonshot/integrations/web_api/routes/runner.py +239 -0
  57. moonshot/integrations/web_api/schemas/__init__.py +0 -0
  58. moonshot/integrations/web_api/schemas/benchmark_runner_dto.py +13 -0
  59. moonshot/integrations/web_api/schemas/cookbook_create_dto.py +19 -0
  60. moonshot/integrations/web_api/schemas/cookbook_response_model.py +9 -0
  61. moonshot/integrations/web_api/schemas/dataset_response_dto.py +9 -0
  62. moonshot/integrations/web_api/schemas/endpoint_create_dto.py +21 -0
  63. moonshot/integrations/web_api/schemas/endpoint_response_model.py +11 -0
  64. moonshot/integrations/web_api/schemas/prompt_response_model.py +14 -0
  65. moonshot/integrations/web_api/schemas/prompt_template_response_model.py +10 -0
  66. moonshot/integrations/web_api/schemas/recipe_create_dto.py +32 -0
  67. moonshot/integrations/web_api/schemas/recipe_response_model.py +7 -0
  68. moonshot/integrations/web_api/schemas/session_create_dto.py +16 -0
  69. moonshot/integrations/web_api/schemas/session_prompt_dto.py +7 -0
  70. moonshot/integrations/web_api/schemas/session_response_model.py +38 -0
  71. moonshot/integrations/web_api/services/__init__.py +0 -0
  72. moonshot/integrations/web_api/services/attack_module_service.py +34 -0
  73. moonshot/integrations/web_api/services/auto_red_team_test_manager.py +86 -0
  74. moonshot/integrations/web_api/services/auto_red_team_test_state.py +57 -0
  75. moonshot/integrations/web_api/services/base_service.py +8 -0
  76. moonshot/integrations/web_api/services/benchmark_result_service.py +25 -0
  77. moonshot/integrations/web_api/services/benchmark_test_manager.py +106 -0
  78. moonshot/integrations/web_api/services/benchmark_test_state.py +56 -0
  79. moonshot/integrations/web_api/services/benchmarking_service.py +31 -0
  80. moonshot/integrations/web_api/services/context_strategy_service.py +22 -0
  81. moonshot/integrations/web_api/services/cookbook_service.py +194 -0
  82. moonshot/integrations/web_api/services/dataset_service.py +20 -0
  83. moonshot/integrations/web_api/services/endpoint_service.py +65 -0
  84. moonshot/integrations/web_api/services/metric_service.py +14 -0
  85. moonshot/integrations/web_api/services/prompt_template_service.py +39 -0
  86. moonshot/integrations/web_api/services/recipe_service.py +155 -0
  87. moonshot/integrations/web_api/services/runner_service.py +147 -0
  88. moonshot/integrations/web_api/services/session_service.py +350 -0
  89. moonshot/integrations/web_api/services/utils/exceptions_handler.py +41 -0
  90. moonshot/integrations/web_api/services/utils/results_formatter.py +47 -0
  91. moonshot/integrations/web_api/status_updater/interface/benchmark_progress_callback.py +14 -0
  92. moonshot/integrations/web_api/status_updater/interface/redteam_progress_callback.py +14 -0
  93. moonshot/integrations/web_api/status_updater/moonshot_ui_webhook.py +72 -0
  94. moonshot/integrations/web_api/types/types.py +99 -0
  95. moonshot/src/__init__.py +0 -0
  96. moonshot/src/api/__init__.py +0 -0
  97. moonshot/src/api/api_connector.py +58 -0
  98. moonshot/src/api/api_connector_endpoint.py +162 -0
  99. moonshot/src/api/api_context_strategy.py +57 -0
  100. moonshot/src/api/api_cookbook.py +160 -0
  101. moonshot/src/api/api_dataset.py +46 -0
  102. moonshot/src/api/api_environment_variables.py +17 -0
  103. moonshot/src/api/api_metrics.py +51 -0
  104. moonshot/src/api/api_prompt_template.py +43 -0
  105. moonshot/src/api/api_recipe.py +182 -0
  106. moonshot/src/api/api_red_teaming.py +59 -0
  107. moonshot/src/api/api_result.py +84 -0
  108. moonshot/src/api/api_run.py +74 -0
  109. moonshot/src/api/api_runner.py +132 -0
  110. moonshot/src/api/api_session.py +290 -0
  111. moonshot/src/configs/__init__.py +0 -0
  112. moonshot/src/configs/env_variables.py +187 -0
  113. moonshot/src/connectors/__init__.py +0 -0
  114. moonshot/src/connectors/connector.py +327 -0
  115. moonshot/src/connectors/connector_prompt_arguments.py +17 -0
  116. moonshot/src/connectors_endpoints/__init__.py +0 -0
  117. moonshot/src/connectors_endpoints/connector_endpoint.py +211 -0
  118. moonshot/src/connectors_endpoints/connector_endpoint_arguments.py +54 -0
  119. moonshot/src/cookbooks/__init__.py +0 -0
  120. moonshot/src/cookbooks/cookbook.py +225 -0
  121. moonshot/src/cookbooks/cookbook_arguments.py +34 -0
  122. moonshot/src/datasets/__init__.py +0 -0
  123. moonshot/src/datasets/dataset.py +255 -0
  124. moonshot/src/datasets/dataset_arguments.py +50 -0
  125. moonshot/src/metrics/__init__.py +0 -0
  126. moonshot/src/metrics/metric.py +192 -0
  127. moonshot/src/metrics/metric_interface.py +95 -0
  128. moonshot/src/prompt_templates/__init__.py +0 -0
  129. moonshot/src/prompt_templates/prompt_template.py +103 -0
  130. moonshot/src/recipes/__init__.py +0 -0
  131. moonshot/src/recipes/recipe.py +340 -0
  132. moonshot/src/recipes/recipe_arguments.py +111 -0
  133. moonshot/src/redteaming/__init__.py +0 -0
  134. moonshot/src/redteaming/attack/__init__.py +0 -0
  135. moonshot/src/redteaming/attack/attack_module.py +618 -0
  136. moonshot/src/redteaming/attack/attack_module_arguments.py +44 -0
  137. moonshot/src/redteaming/attack/context_strategy.py +131 -0
  138. moonshot/src/redteaming/context_strategy/__init__.py +0 -0
  139. moonshot/src/redteaming/context_strategy/context_strategy_interface.py +46 -0
  140. moonshot/src/redteaming/session/__init__.py +0 -0
  141. moonshot/src/redteaming/session/chat.py +209 -0
  142. moonshot/src/redteaming/session/red_teaming_progress.py +128 -0
  143. moonshot/src/redteaming/session/red_teaming_type.py +6 -0
  144. moonshot/src/redteaming/session/session.py +775 -0
  145. moonshot/src/results/__init__.py +0 -0
  146. moonshot/src/results/result.py +119 -0
  147. moonshot/src/results/result_arguments.py +44 -0
  148. moonshot/src/runners/__init__.py +0 -0
  149. moonshot/src/runners/runner.py +476 -0
  150. moonshot/src/runners/runner_arguments.py +46 -0
  151. moonshot/src/runners/runner_type.py +6 -0
  152. moonshot/src/runs/__init__.py +0 -0
  153. moonshot/src/runs/run.py +344 -0
  154. moonshot/src/runs/run_arguments.py +162 -0
  155. moonshot/src/runs/run_progress.py +145 -0
  156. moonshot/src/runs/run_status.py +10 -0
  157. moonshot/src/storage/__init__.py +0 -0
  158. moonshot/src/storage/db_interface.py +128 -0
  159. moonshot/src/storage/io_interface.py +31 -0
  160. moonshot/src/storage/storage.py +525 -0
  161. moonshot/src/utils/__init__.py +0 -0
  162. moonshot/src/utils/import_modules.py +96 -0
  163. 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]
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