aiverify-moonshot 0.6.2__py3-none-any.whl → 0.6.3__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 (26) hide show
  1. {aiverify_moonshot-0.6.2.dist-info → aiverify_moonshot-0.6.3.dist-info}/METADATA +2 -2
  2. {aiverify_moonshot-0.6.2.dist-info → aiverify_moonshot-0.6.3.dist-info}/RECORD +25 -25
  3. aiverify_moonshot-0.6.3.dist-info/licenses/NOTICES.md +1187 -0
  4. moonshot/integrations/cli/__main__.py +1 -3
  5. moonshot/integrations/cli/redteam/session.py +8 -8
  6. moonshot/integrations/web_api/app.py +1 -1
  7. moonshot/integrations/web_api/routes/benchmark_result.py +1 -0
  8. moonshot/integrations/web_api/routes/bookmark.py +5 -2
  9. moonshot/integrations/web_api/routes/context_strategy.py +3 -1
  10. moonshot/integrations/web_api/routes/prompt_template.py +1 -0
  11. moonshot/integrations/web_api/schemas/cookbook_create_dto.py +4 -2
  12. moonshot/integrations/web_api/schemas/prompt_response_model.py +0 -1
  13. moonshot/integrations/web_api/schemas/recipe_create_dto.py +2 -1
  14. moonshot/integrations/web_api/services/context_strategy_service.py +1 -4
  15. moonshot/integrations/web_api/services/cookbook_service.py +0 -2
  16. moonshot/integrations/web_api/services/session_service.py +5 -5
  17. moonshot/integrations/web_api/services/utils/exceptions_handler.py +47 -10
  18. moonshot/integrations/web_api/services/utils/results_formatter.py +25 -16
  19. moonshot/integrations/web_api/status_updater/interface/benchmark_progress_callback.py +3 -3
  20. moonshot/integrations/web_api/status_updater/interface/redteam_progress_callback.py +3 -3
  21. moonshot/src/cookbooks/cookbook_arguments.py +1 -1
  22. moonshot/src/redteaming/attack/attack_module.py +9 -3
  23. aiverify_moonshot-0.6.2.dist-info/licenses/NOTICES.md +0 -2506
  24. {aiverify_moonshot-0.6.2.dist-info → aiverify_moonshot-0.6.3.dist-info}/WHEEL +0 -0
  25. {aiverify_moonshot-0.6.2.dist-info → aiverify_moonshot-0.6.3.dist-info}/licenses/AUTHORS.md +0 -0
  26. {aiverify_moonshot-0.6.2.dist-info → aiverify_moonshot-0.6.3.dist-info}/licenses/LICENSE.md +0 -0
@@ -1,10 +1,9 @@
1
- import sys
2
1
  import warnings
3
2
 
4
3
  from moonshot.integrations.cli.cli import CommandLineInterface
5
4
 
6
5
 
7
- def start_app(cli_command = None):
6
+ def start_app(cli_command=None):
8
7
  """
9
8
  Run the Moonshot application
10
9
  """
@@ -22,4 +21,3 @@ def start_app(cli_command = None):
22
21
  else:
23
22
  # Show help if no command is provided
24
23
  cli_instance.onecmd("help")
25
-
@@ -58,7 +58,7 @@ def new_session(args) -> None:
58
58
  - context_strategy (str, optional): The context strategy to be used.
59
59
  - prompt_template (str, optional): The prompt template to be used.
60
60
  - endpoints (str, optional): The list of endpoints for the runner."""
61
- global active_session
61
+ global active_session # noqa: F824
62
62
 
63
63
  try:
64
64
  required_parameters = [("runner_id", str)]
@@ -136,7 +136,7 @@ def use_session(args) -> None:
136
136
  Args:
137
137
  args (Namespace): The arguments passed to the function.
138
138
  """
139
- global active_session
139
+ global active_session # noqa: F824
140
140
 
141
141
  # Load session metadata
142
142
  try:
@@ -168,7 +168,7 @@ def show_prompts() -> None:
168
168
  """
169
169
  Shows the chat table in a session so that users don't have to restart a session to view the chat table
170
170
  """
171
- global active_session
171
+ global active_session # noqa: F824
172
172
 
173
173
  if not active_session:
174
174
  print(ERROR_RED_TEAMING_SHOW_PROMPTS_NO_ACTIVE_SESSION_VALIDATION)
@@ -181,7 +181,7 @@ def end_session() -> None:
181
181
  """
182
182
  Ends the current session by clearing active_session variable.
183
183
  """
184
- global active_session
184
+ global active_session # noqa: F824
185
185
  active_session.clear()
186
186
 
187
187
 
@@ -249,7 +249,7 @@ def update_chat_display() -> None:
249
249
  The table includes columns for the chat ID, prepared prompts, and the prompt/response pairs.
250
250
  If there is no active session, a message is printed to the console.
251
251
  """
252
- global active_session
252
+ global active_session # noqa: F824
253
253
 
254
254
  if active_session:
255
255
  list_of_endpoint_chats = api_get_all_chats_from_session(
@@ -311,7 +311,7 @@ def add_bookmark(args) -> None:
311
311
 
312
312
  If there is no active session, a message is printed to the console and the function returns.
313
313
  """
314
- global active_session
314
+ global active_session # noqa: F824
315
315
 
316
316
  if active_session:
317
317
  try:
@@ -372,7 +372,7 @@ def use_bookmark(args) -> None:
372
372
 
373
373
  If there is no active session, a message is printed to the console and the function returns.
374
374
  """
375
- global active_session
375
+ global active_session # noqa: F824
376
376
  if active_session:
377
377
  try:
378
378
  bookmark_name = args.bookmark_name
@@ -747,7 +747,7 @@ def _reload_session(runner_id: str) -> None:
747
747
  Args:
748
748
  runner_id (str): The ID of the runner for which the session metadata needs to be reloaded.
749
749
  """
750
- global active_session
750
+ global active_session # noqa: F824
751
751
  try:
752
752
  session_metadata = api_load_session(runner_id)
753
753
  if not session_metadata:
@@ -71,7 +71,7 @@ def create_app(cfg: providers.Configuration) -> CustomFastAPI:
71
71
  }
72
72
 
73
73
  app: CustomFastAPI = CustomFastAPI(
74
- title="Project Moonshot", version="0.6.2", **app_kwargs
74
+ title="Project Moonshot", version="0.6.3", **app_kwargs
75
75
  )
76
76
 
77
77
  if cfg.cors.enabled():
@@ -131,6 +131,7 @@ async def get_one_results(
131
131
  status_code=500, detail=f"Failed to retrieve result: {e.msg}"
132
132
  )
133
133
 
134
+
134
135
  @router.delete("/api/v1/benchmarks/results/{result_id}")
135
136
  @inject
136
137
  def delete_result(
@@ -1,4 +1,3 @@
1
- import os
2
1
  from typing import Optional
3
2
 
4
3
  from dependency_injector.wiring import Provide, inject
@@ -138,6 +137,8 @@ def delete_bookmark(
138
137
  raise HTTPException(
139
138
  status_code=500, detail=f"Failed to delete bookmark: {e.msg}"
140
139
  )
140
+
141
+
141
142
  @router.get(
142
143
  "/api/v1/bookmarks/export", response_description="Exporting Bookmark to JSON file"
143
144
  )
@@ -160,7 +161,9 @@ def export_bookbookmarks(
160
161
  """
161
162
  try:
162
163
  file_path = bookmark_service.export_bookmarks(export_file_name)
163
- return FileResponse(file_path, media_type="application/json", filename=export_file_name)
164
+ return FileResponse(
165
+ file_path, media_type="application/json", filename=export_file_name
166
+ )
164
167
  except ServiceException as e:
165
168
  if e.error_code == "FileNotFound":
166
169
  raise HTTPException(
@@ -7,6 +7,7 @@ from ..services.utils.exceptions_handler import ServiceException
7
7
 
8
8
  router = APIRouter(tags=["Context Strategy"])
9
9
 
10
+
10
11
  @router.get("/api/v1/context-strategies")
11
12
  @inject
12
13
  def get_all_context_strategies(
@@ -46,7 +47,8 @@ def get_all_context_strategies(
46
47
  status_code=500,
47
48
  detail=f"Failed to retrieve context strategies: {e.msg}",
48
49
  )
49
-
50
+
51
+
50
52
  @router.get("/api/v1/context-strategies/name")
51
53
  @inject
52
54
  def get_all_context_strategies_name(
@@ -87,6 +87,7 @@ def get_all_prompt_templates_names(
87
87
  detail=f"Failed to retrieve prompt template names: {e.msg}",
88
88
  )
89
89
 
90
+
90
91
  @router.delete("/api/v1/prompt-templates/{prompt_template_name}")
91
92
  @inject
92
93
  def delete_prompt_template(
@@ -1,9 +1,11 @@
1
1
  from typing import Optional
2
2
 
3
+ from pydantic import Field
4
+
3
5
  from moonshot.src.cookbooks.cookbook_arguments import (
4
6
  CookbookArguments as CookbookPydanticModel,
5
7
  )
6
- from pydantic import Field
8
+
7
9
 
8
10
  class CookbookCreateDTO(CookbookPydanticModel):
9
11
  id: Optional[str] = None
@@ -20,4 +22,4 @@ class CookbookUpdateDTO(CookbookPydanticModel):
20
22
  description: Optional[str] = Field(default=None, min_length=1)
21
23
  tags: Optional[list[str]] = None
22
24
  categories: Optional[list[str]] = None
23
- recipes: Optional[list[str]] = Field(default=None, min_length=1)
25
+ recipes: Optional[list[str]] = Field(default=None, min_length=1)
@@ -3,7 +3,6 @@ from pydantic import BaseModel, RootModel
3
3
  from ..schemas.session_response_model import ChatRecord
4
4
 
5
5
 
6
-
7
6
  class PromptInfo(BaseModel):
8
7
  current_runner_id: str
9
8
  current_chats: dict[str, list[ChatRecord]]
@@ -1,8 +1,9 @@
1
1
  from typing import Optional
2
2
 
3
+ from pydantic import Field
4
+
3
5
  from moonshot.src.recipes.recipe_arguments import RecipeArguments as RecipePydanticModel
4
6
 
5
- from pydantic import Field
6
7
 
7
8
  class RecipeCreateDTO(RecipePydanticModel):
8
9
  id: Optional[str] = None
@@ -1,17 +1,14 @@
1
- from typing import Any
2
-
3
1
  from .... import api as moonshot_api
4
2
  from ..services.utils.exceptions_handler import exception_handler
5
3
  from .base_service import BaseService
6
4
 
7
5
 
8
6
  class ContextStrategyService(BaseService):
9
-
10
7
  @exception_handler
11
8
  def get_ctx_strategy(self) -> list[dict]:
12
9
  strategies = moonshot_api.api_get_all_context_strategy_metadata()
13
10
  return strategies
14
-
11
+
15
12
  @exception_handler
16
13
  def get_ctx_strategy_name(self) -> list[str]:
17
14
  strategies = moonshot_api.api_get_all_context_strategies()
@@ -200,8 +200,6 @@ def cookbook_has_categories(categories: str, cookbook: Cookbook) -> bool:
200
200
  )
201
201
 
202
202
 
203
-
204
-
205
203
  @staticmethod
206
204
  def cookbook_metrics_dependency(cookbook: Cookbook) -> dict | None:
207
205
  """
@@ -100,15 +100,15 @@ class SessionService(BaseService):
100
100
  retn_session = []
101
101
  runners_with_session = moonshot_api.api_get_all_runner()
102
102
  sessions_metadata_dicts = moonshot_api.api_get_all_session_metadata()
103
-
104
- runners_dict = {runner['id']: runner for runner in runners_with_session}
105
-
103
+
104
+ runners_dict = {runner["id"]: runner for runner in runners_with_session}
105
+
106
106
  for session in sessions_metadata_dicts:
107
107
  sess_id = session.get("session_id")
108
108
  if sess_id in runners_dict:
109
- session['description'] = runners_dict[sess_id]['description']
109
+ session["description"] = runners_dict[sess_id]["description"]
110
110
  retn_session.append(session)
111
-
111
+
112
112
  return [
113
113
  SessionMetadataModel(**metadata) for metadata in sessions_metadata_dicts
114
114
  ]
@@ -1,41 +1,78 @@
1
1
  import asyncio
2
2
  from typing import Any, Callable
3
+
3
4
  from pydantic import ValidationError
4
5
 
6
+
5
7
  class ServiceException(Exception):
6
8
  error_code: str
7
9
  msg: str
8
10
 
9
- def __init__(self, msg: str, method_name: str, error_code: str = 'UnknownSessionError'):
11
+ def __init__(
12
+ self, msg: str, method_name: str, error_code: str = "UnknownSessionError"
13
+ ):
10
14
  self.error_code = error_code
11
15
  message = f"[ServiceException] {error_code} in {method_name} - {msg}"
12
- self.msg = message
16
+ self.msg = message
13
17
  super().__init__(message)
14
18
 
19
+
15
20
  def exception_handler(func: Callable[..., Any]) -> Callable[..., Any]:
16
21
  if asyncio.iscoroutinefunction(func):
22
+
17
23
  async def async_wrapper(*args: Any, **kwargs: Any) -> Any:
18
24
  try:
19
25
  return await func(*args, **kwargs)
20
26
  except FileNotFoundError as e:
21
- raise ServiceException(f"A file not found error occurred: {e}", func.__name__, "FileNotFound")
27
+ raise ServiceException(
28
+ f"A file not found error occurred: {e}",
29
+ func.__name__,
30
+ "FileNotFound",
31
+ )
22
32
  except ValidationError as e:
23
- raise ServiceException(f"A validation error occurred: {e}", func.__name__, "ValidationError")
33
+ raise ServiceException(
34
+ f"A validation error occurred: {e}",
35
+ func.__name__,
36
+ "ValidationError",
37
+ )
24
38
  except ValueError as e:
25
- raise ServiceException(f"An value error occurred: {e}", func.__name__, "ValueError")
39
+ raise ServiceException(
40
+ f"An value error occurred: {e}", func.__name__, "ValueError"
41
+ )
26
42
  except Exception as e:
27
- raise ServiceException(f"An unexpected error occurred: {e}", func.__name__, "UnexpectedError")
43
+ raise ServiceException(
44
+ f"An unexpected error occurred: {e}",
45
+ func.__name__,
46
+ "UnexpectedError",
47
+ )
48
+
28
49
  return async_wrapper
29
50
  else:
51
+
30
52
  def wrapper(*args: Any, **kwargs: Any) -> Any:
31
53
  try:
32
54
  return func(*args, **kwargs)
33
55
  except FileNotFoundError as e:
34
- raise ServiceException(f"A file not found error occurred: {e}", func.__name__, "FileNotFound")
56
+ raise ServiceException(
57
+ f"A file not found error occurred: {e}",
58
+ func.__name__,
59
+ "FileNotFound",
60
+ )
35
61
  except ValidationError as e:
36
- raise ServiceException(f"A validation error occurred: {e}", func.__name__, "ValidationError")
62
+ raise ServiceException(
63
+ f"A validation error occurred: {e}",
64
+ func.__name__,
65
+ "ValidationError",
66
+ )
37
67
  except ValueError as e:
38
- raise ServiceException(f"An value error occurred: {e}", func.__name__, "ValueError")
68
+ raise ServiceException(
69
+ f"An value error occurred: {e}", func.__name__, "ValueError"
70
+ )
39
71
  except Exception as e:
40
- raise ServiceException(f"An unexpected error occurred: {e}", func.__name__, "UnexpectedError")
72
+ raise ServiceException(
73
+ f"An unexpected error occurred: {e}",
74
+ func.__name__,
75
+ "UnexpectedError",
76
+ )
77
+
41
78
  return wrapper
@@ -1,18 +1,20 @@
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]]]]]]]]:
1
+ def transform_web_format(
2
+ original_dict: dict[str, dict[str, list[dict[str, dict[str, float]]]]]
3
+ ) -> dict[str, dict[str, list[dict[str, list[dict[str, list[dict[str, float]]]]]]]]:
2
4
  transformed = {"metadata": original_dict["metadata"], "results": {"cookbooks": []}}
3
-
5
+
4
6
  for cookbook_name, cookbook_data in original_dict.items():
5
7
  if cookbook_name == "metadata":
6
8
  continue # Skip the metadata entry
7
-
9
+
8
10
  cookbook_entry = {"id": cookbook_name, "recipes": []}
9
11
  for recipe_name, recipe_data in cookbook_data.items():
10
12
  recipe_entry = {"id": recipe_name, "models": []}
11
-
13
+
12
14
  for model_data_str, model_data in recipe_data.items():
13
15
  # Extract model, recipe, dataset, prompt_template from the string
14
16
  model, _, dataset, prompt_template = eval(model_data_str)
15
-
17
+
16
18
  model_entry = {
17
19
  "id": model,
18
20
  "datasets": [
@@ -21,27 +23,34 @@ def transform_web_format(original_dict: dict[str, dict[str, list[dict[str, dict[
21
23
  "prompt_templates": [
22
24
  {
23
25
  "id": prompt_template,
24
- "metrics": model_data["results"]
26
+ "metrics": model_data["results"],
25
27
  }
26
- ]
28
+ ],
27
29
  }
28
- ]
30
+ ],
29
31
  }
30
-
32
+
31
33
  # 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)
34
+ existing_model = next(
35
+ (m for m in recipe_entry["models"] if m["id"] == model), None
36
+ )
33
37
  if existing_model:
34
38
  # 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)
39
+ existing_dataset = next(
40
+ (d for d in existing_model["datasets"] if d["id"] == dataset),
41
+ None,
42
+ )
36
43
  if existing_dataset:
37
- existing_dataset["prompt_templates"].append(model_entry["datasets"][0]["prompt_templates"][0])
44
+ existing_dataset["prompt_templates"].append(
45
+ model_entry["datasets"][0]["prompt_templates"][0]
46
+ )
38
47
  else:
39
48
  existing_model["datasets"].append(model_entry["datasets"][0])
40
49
  else:
41
50
  recipe_entry["models"].append(model_entry)
42
-
51
+
43
52
  cookbook_entry["recipes"].append(recipe_entry)
44
-
53
+
45
54
  transformed["results"]["cookbooks"].append(cookbook_entry)
46
-
47
- return transformed
55
+
56
+ return transformed
@@ -1,14 +1,14 @@
1
1
  from abc import ABC, abstractmethod
2
+
2
3
  from ...types.types import TestRunProgress
3
4
 
5
+
4
6
  class InterfaceBenchmarkProgressCallback(ABC):
5
7
  """
6
8
  The interface to implement for handling of benchmark progress updates from moonshot library
7
9
 
8
10
  """
11
+
9
12
  @abstractmethod
10
13
  def on_progress_update(self, progress_data: TestRunProgress) -> None:
11
14
  pass
12
-
13
-
14
-
@@ -1,14 +1,14 @@
1
1
  from abc import ABC, abstractmethod
2
+
2
3
  from ...types.types import TestRunProgress
3
4
 
5
+
4
6
  class InterfaceRedTeamProgressCallback(ABC):
5
7
  """
6
8
  The interface to implement for handling of redteam progress updates from moonshot library
7
9
 
8
10
  """
11
+
9
12
  @abstractmethod
10
13
  def on_art_progress_update(self, progress_data: TestRunProgress) -> None:
11
14
  pass
12
-
13
-
14
-
@@ -8,7 +8,7 @@ class CookbookArguments(BaseModel):
8
8
 
9
9
  description: str # description (str): A brief description of the Cookbook.
10
10
 
11
- tags: list[str] # tags (list): The list of tags in the Cookbook.
11
+ tags: list[str] # tags (list): The list of tags in the Cookbook.
12
12
 
13
13
  categories: list[str] # categories (list): The list of categories in the Cookbook.
14
14
 
@@ -649,7 +649,7 @@ class RedTeamingPromptArguments(BaseModel):
649
649
 
650
650
  This method collects all the attributes of the RedTeamingPromptArguments instance and forms a tuple
651
651
  with the attribute values in this specific order: conn_id, cs_id, pt_id, am_id, me_id, original_prompt,
652
- connector_prompt.prompt, system_prompt, connector_prompt.predicted_results.response,
652
+ connector_prompt.prompt, system_prompt, connector_prompt.predicted_results.response,
653
653
  connector_prompt.duration, start_time.
654
654
 
655
655
  Returns:
@@ -664,7 +664,9 @@ class RedTeamingPromptArguments(BaseModel):
664
664
  self.original_prompt,
665
665
  self.connector_prompt.prompt,
666
666
  self.system_prompt,
667
- self.connector_prompt.predicted_results.response if self.connector_prompt.predicted_results else "",
667
+ self.connector_prompt.predicted_results.response
668
+ if self.connector_prompt.predicted_results
669
+ else "",
668
670
  str(self.connector_prompt.duration),
669
671
  self.start_time,
670
672
  )
@@ -689,7 +691,11 @@ class RedTeamingPromptArguments(BaseModel):
689
691
  "original_prompt": self.original_prompt,
690
692
  "prepared_prompt": self.connector_prompt.prompt,
691
693
  "system_prompt": self.system_prompt,
692
- "response": self.connector_prompt.predicted_results.response if self.connector_prompt.predicted_results else "",
694
+ "response": (
695
+ self.connector_prompt.predicted_results.response
696
+ if self.connector_prompt.predicted_results
697
+ else ""
698
+ ),
693
699
  "duration": str(self.connector_prompt.duration),
694
700
  "start_time": self.start_time,
695
701
  }