aiverify-moonshot 0.4.5__py3-none-any.whl → 0.4.6__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: aiverify-moonshot
3
- Version: 0.4.5
3
+ Version: 0.4.6
4
4
  Summary: AI Verify advances Gen AI testing with Project Moonshot.
5
5
  Project-URL: Repository, https://github.com/aiverify-foundation/moonshot
6
6
  Project-URL: Documentation, https://aiverify-foundation.github.io/moonshot/
@@ -18,6 +18,7 @@ Requires-Python: >=3.11
18
18
  Requires-Dist: datasets==2.20.0
19
19
  Requires-Dist: ijson==3.3.0
20
20
  Requires-Dist: jinja2==3.1.4
21
+ Requires-Dist: numpy==1.26.4
21
22
  Requires-Dist: pandas==2.2.2
22
23
  Requires-Dist: pydantic==2.8.2
23
24
  Requires-Dist: pyparsing==3.1.2
@@ -45,7 +46,7 @@ Description-Content-Type: text/markdown
45
46
 
46
47
  ![Moonshot Logo](https://github.com/aiverify-foundation/moonshot/raw/main/misc/aiverify-moonshot-logo.png)
47
48
 
48
- **Version 0.4.5**
49
+ **Version 0.4.6**
49
50
 
50
51
  A simple and modular tool to evaluate any LLM application.
51
52
 
@@ -6,21 +6,22 @@ moonshot/integrations/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
6
6
  moonshot/integrations/cli/__main__.py,sha256=0VnYSj2AayvDCZ3uXpldPcjMHt2Yd7BWojWzFOGSSl4,679
7
7
  moonshot/integrations/cli/active_session_cfg.py,sha256=n8hOFxFjvz26qbEFY4q7iPUZYrGLoeCmXJxmOb_xWUE,20
8
8
  moonshot/integrations/cli/cli.py,sha256=9tnzcxcSOjblxCUpyh3pK0ke0bLs3s-63OxXtYoZI2g,2769
9
+ moonshot/integrations/cli/cli_errors.py,sha256=BhA7k7leuPe3ms2W25iip_yqjrhWKmTaZ2iz1OSjBvE,22981
9
10
  moonshot/integrations/cli/benchmark/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
11
  moonshot/integrations/cli/benchmark/benchmark.py,sha256=QUxr6DU11-XeH6Y3j1uPsZsotshgy64G_cWNf0Rn2_U,6303
11
- moonshot/integrations/cli/benchmark/cookbook.py,sha256=9mNuqsaVFCfXnLgVxJQ-fzwSgH8j082NR2gE-GPQbG8,22183
12
- moonshot/integrations/cli/benchmark/datasets.py,sha256=E-kreuXkrNU39sFuVWGhutFHfoEhsVjFK4tmq7YQwxs,7193
13
- moonshot/integrations/cli/benchmark/metrics.py,sha256=6wLn3WyqgUJKCRvblxiyx8X4nQ7gA1sKGcC_DNBIWBo,6351
14
- moonshot/integrations/cli/benchmark/recipe.py,sha256=EYv94Qjq2hqn1zz9NzWaINEY9DNdY7TkSS57xHv6ymQ,22698
15
- moonshot/integrations/cli/benchmark/result.py,sha256=U0SsjJYNQJYP_EZ3pAil4VaOQLMZHchfzq982nXU-jE,9486
16
- moonshot/integrations/cli/benchmark/run.py,sha256=Rqdb_FspgQQhkLORjgdiyaijk7HTxM39giOzXpBXA1k,6161
17
- moonshot/integrations/cli/benchmark/runner.py,sha256=nAnNKihQD0AScl6vPFiFH_9MZU4ppeMG34QaLRidqvU,6602
12
+ moonshot/integrations/cli/benchmark/cookbook.py,sha256=h9exPhLKLRa9a1qWB2WptZ35gcVov332tjHDO9ECs0o,29639
13
+ moonshot/integrations/cli/benchmark/datasets.py,sha256=Uq5XMNWUp775sz9jCZUZHHmkumPFI7cHVRueHgWm70Q,8965
14
+ moonshot/integrations/cli/benchmark/metrics.py,sha256=ATZtVOj3kjGuyxOgfAO1QzTDeAOEjbSeQYr3NOCmTCQ,8070
15
+ moonshot/integrations/cli/benchmark/recipe.py,sha256=yVFX3pwNzDL0a95rjlQd4cek06M9blv5jIeYB26jOKk,32481
16
+ moonshot/integrations/cli/benchmark/result.py,sha256=TGlIuDkPB1Cfu1u2uyDsWtgQxTOoNdGDzc0vCnGC1zk,11152
17
+ moonshot/integrations/cli/benchmark/run.py,sha256=HBztvG_Zkg1ZAWsFv0QDE43FaEmx92vTWc4h1U3VesU,7438
18
+ moonshot/integrations/cli/benchmark/runner.py,sha256=Y4Vt6Qqn9QzsM6eLUM9m2_XKkW3ctu-2jMTSei_TDPU,7098
18
19
  moonshot/integrations/cli/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
20
  moonshot/integrations/cli/common/common.py,sha256=hSvxj-T91nhKfJtQqxrIPgYdS8P_g7wbOwpFpqBg90I,3090
20
- moonshot/integrations/cli/common/connectors.py,sha256=8_U7KJzfsS9L13dMbouk5JKOy_ow4UhrILICCw27Q5c,13909
21
- moonshot/integrations/cli/common/dataset.py,sha256=KZuwSV4Di7C378Aa2bRxIKCd03oo6HdMTEZpBZSQb5w,3113
21
+ moonshot/integrations/cli/common/connectors.py,sha256=0KoCji-a6AJ0GLqpDdgm4mcfj-FzNW2DOsuQ0Fi_gwc,19445
22
+ moonshot/integrations/cli/common/dataset.py,sha256=6v5qXgWBGhT4Rl5uuqPMwLeFF0c5m7ECzyGe1IFXNW0,4743
22
23
  moonshot/integrations/cli/common/display_helper.py,sha256=8rVowW33XK0j0C_X_H1jUbFlFk1Y2WpzxmIUE3Ca5Co,1459
23
- moonshot/integrations/cli/common/prompt_template.py,sha256=KzawF2VaiWUKzRIrXX_TaHboiPVllSiqz5I_o2TqGiA,4812
24
+ moonshot/integrations/cli/common/prompt_template.py,sha256=2cXWeHh16EUvzYFre7juMxT2R0x3kqDJVucH0bKLmCU,6351
24
25
  moonshot/integrations/cli/initialisation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
26
  moonshot/integrations/cli/initialisation/initialisation.py,sha256=zMjklhoBlYLPshe7Q16vBBbOfhbPjZc4_ooywAFp2XY,387
26
27
  moonshot/integrations/cli/redteam/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -28,12 +29,12 @@ moonshot/integrations/cli/redteam/attack_module.py,sha256=sjjQdBno7rXNfrXqns55ER
28
29
  moonshot/integrations/cli/redteam/context_strategy.py,sha256=gLNgnd1oHWD1X93BQoKlR7G8b5g9P6AcKFLlE3WvETk,7065
29
30
  moonshot/integrations/cli/redteam/prompt_template.py,sha256=rWINvMFLax8ynIFJoX93xsB1cWJ8-dQ1nRyqgdri2yQ,2079
30
31
  moonshot/integrations/cli/redteam/redteam.py,sha256=144tVuiSWBLseC0EvvIuevHYJhqn39xvg36-1cLgGWQ,4257
31
- moonshot/integrations/cli/redteam/session.py,sha256=auZ73LfMAGmT1jLJUjqY6oAsMWoSzHstiRGA8DKF6A4,33652
32
+ moonshot/integrations/cli/redteam/session.py,sha256=lucUS8Ejcg9PQKVhVj1VUZECe2pvFwbwoSbsVl0BazI,37672
32
33
  moonshot/integrations/cli/utils/process_data.py,sha256=QVL5vp2_8ZgGicmCAdeYEHkeb6f-NC775-JCzWziNiU,1901
33
34
  moonshot/integrations/web_api/.env.dev,sha256=0z5_Ut8rF-UqFZtgjkH2qoqORhD5_nSs2w_OeX2SteI,182
34
35
  moonshot/integrations/web_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
36
  moonshot/integrations/web_api/__main__.py,sha256=MdnLi_ZF-olAAEJwTPU1iGYFYwo-fNWNT2qfchkH3y4,2050
36
- moonshot/integrations/web_api/app.py,sha256=4EzGEwvFh6any62ZJNGH2GCXUOPjqNYURL0Toe2rTNI,3651
37
+ moonshot/integrations/web_api/app.py,sha256=x9QTqkHy4zfnQTA0UJVFHht0vSuDs1BZphjLfhFjsVY,3651
37
38
  moonshot/integrations/web_api/container.py,sha256=DVkJG_qm7ItcG6tgMYOqIj07wpKhPWOOfy6-bEv72y4,5915
38
39
  moonshot/integrations/web_api/logging_conf.py,sha256=t3EGRV6tZhV732KXe8_Tiy0fiwVAWxZX5Tt8VTgrrfg,3388
39
40
  moonshot/integrations/web_api/log/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -95,8 +96,9 @@ moonshot/integrations/web_api/status_updater/interface/redteam_progress_callback
95
96
  moonshot/integrations/web_api/temp/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
96
97
  moonshot/integrations/web_api/types/types.py,sha256=AN0Xf61lx2c5AFAYoXA8mVL5iufVBpwYlIPdo8gv-ls,2395
97
98
  moonshot/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
+ moonshot/src/messages_constants.py,sha256=pFhm7c2UkdX-XPr62bj6mArf5xrRmktuh_ZiUICJHd0,2352
98
100
  moonshot/src/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
- moonshot/src/api/api_bookmark.py,sha256=Nr0B3S6UUnNbuvXyL-dz8IMyFxCywU1u4UL2D8TjHik,3004
101
+ moonshot/src/api/api_bookmark.py,sha256=FhtSojdw8wfzJXQnH9VnkwsuqRf_c_y6LH0oOQA48Dc,2926
100
102
  moonshot/src/api/api_connector.py,sha256=JpwLFd7Vh1LRz6oB8fhO2iufMbSTt5RmrMe7nt56bPM,2257
101
103
  moonshot/src/api/api_connector_endpoint.py,sha256=UUuHzrgoj0bWcbOXPUJh7FEg-pzBOSo6DLgwqCZnLmw,5503
102
104
  moonshot/src/api/api_context_strategy.py,sha256=WqzUEw3f7gROJlc_G7bsGkuP3nO1HycFzn3dfcxzaoc,2153
@@ -111,8 +113,8 @@ moonshot/src/api/api_result.py,sha256=M5zKF7ytKp237UZusLSYJ7QVfui85Ys0WEaYySGcAK
111
113
  moonshot/src/api/api_run.py,sha256=3PrETAVcFnJ09R0-xhWiFkEfqL6eYj4B2voEGJDPznU,2936
112
114
  moonshot/src/api/api_runner.py,sha256=cH0rxWREjc2qKmt4Tuwr-fEMrYDBE_TKRw0jOohNEgU,4179
113
115
  moonshot/src/api/api_session.py,sha256=OGH05ZxAwo_hKI-RNaJ-jCp_v-zcTm-9bHUclpq2z4Q,10978
114
- moonshot/src/bookmark/bookmark.py,sha256=KZoKOyJseW02IS5KqfCIMusFiNwESBxOAvOZTwO7YUw,8867
115
- moonshot/src/bookmark/bookmark_arguments.py,sha256=rwgUPMXmDLNaHfJvRTR4GaZ8vwRilchzOg9bZJQoe_8,1130
116
+ moonshot/src/bookmark/bookmark.py,sha256=5TJ-q7mGpULqaH5osdB2kThP4bKMIO6nWqrXhvjAy4U,11270
117
+ moonshot/src/bookmark/bookmark_arguments.py,sha256=cB5m2zB8255WVdacmC2-ZYNyaoK4-gOM_Qwb_JDR-34,1449
116
118
  moonshot/src/configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
117
119
  moonshot/src/configs/env_variables.py,sha256=eF__UJN37LCzIB4pv_T7G-kQHlOa657QA7IpL1d_0MM,7150
118
120
  moonshot/src/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -151,7 +153,7 @@ moonshot/src/results/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
151
153
  moonshot/src/results/result.py,sha256=o56SdhYH-XVfpeeKhN495dJPkU035MmTjRUx48q53lo,4527
152
154
  moonshot/src/results/result_arguments.py,sha256=mTR7yajY72PFglfAaa1ajJfvYNV4IBGLXS4VaD53-8c,1334
153
155
  moonshot/src/runners/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
154
- moonshot/src/runners/runner.py,sha256=Wsvdzcw4KOa-ppgGVRGSK2YxLfXK-daHDw3k5jETv-4,21197
156
+ moonshot/src/runners/runner.py,sha256=nnYiMHZUSu35jzHoeiEqADhc7iHLKnViyUbd_Qg8WZs,21203
155
157
  moonshot/src/runners/runner_arguments.py,sha256=Bg4OPSmgr9jZKNAwPH0T3epEHw-6qGrflszFc6oMyEU,1640
156
158
  moonshot/src/runners/runner_type.py,sha256=jOfnAnaCYp-rPTRJXhM8hin_dinlR0sMwmimQXvLcJ0,100
157
159
  moonshot/src/runs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -169,9 +171,9 @@ moonshot/src/utils/import_modules.py,sha256=T9zTN59PFnvY2rjyWhSV9KSIAHxWV1pyBemF
169
171
  moonshot/src/utils/log.py,sha256=YNgD7Eh2OT36XlmVBKCGUTAh9TRp4Akfe4kDdvHASgs,2502
170
172
  moonshot/src/utils/pagination.py,sha256=5seymyRoqyENIhKllAatr1T91kMCGFslcvRnJHyMSvc,814
171
173
  moonshot/src/utils/timeit.py,sha256=TvuF0w8KWhp0oZFY0cUU3UY0xlGKjchb0OkfYfgVTlc,866
172
- aiverify_moonshot-0.4.5.dist-info/METADATA,sha256=d8sIDGy6Ywuov6QnMj62fa6Qu5Uvbekv4_rBGeLObWM,12368
173
- aiverify_moonshot-0.4.5.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
174
- aiverify_moonshot-0.4.5.dist-info/licenses/AUTHORS.md,sha256=mmAbe3i3sT8JZHJMBhxp3i1xRehV0g7WB4T_eyIBuBs,59
175
- aiverify_moonshot-0.4.5.dist-info/licenses/LICENSE.md,sha256=mDOKOkWFbJmUORaAchXByEVGC1jw37QRn-zS14wY_wM,11347
176
- aiverify_moonshot-0.4.5.dist-info/licenses/NOTICES.md,sha256=0Ikx6IBGGQEOJeNb2MkRoXxTXwrtlMz6EDgLBFIz6v0,179593
177
- aiverify_moonshot-0.4.5.dist-info/RECORD,,
174
+ aiverify_moonshot-0.4.6.dist-info/METADATA,sha256=PM15lwqxY3nBr-fbxQp44E_wMZyxKBOCq0r_hYiSFTI,12397
175
+ aiverify_moonshot-0.4.6.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
176
+ aiverify_moonshot-0.4.6.dist-info/licenses/AUTHORS.md,sha256=mmAbe3i3sT8JZHJMBhxp3i1xRehV0g7WB4T_eyIBuBs,59
177
+ aiverify_moonshot-0.4.6.dist-info/licenses/LICENSE.md,sha256=mDOKOkWFbJmUORaAchXByEVGC1jw37QRn-zS14wY_wM,11347
178
+ aiverify_moonshot-0.4.6.dist-info/licenses/NOTICES.md,sha256=0Ikx6IBGGQEOJeNb2MkRoXxTXwrtlMz6EDgLBFIz6v0,179593
179
+ aiverify_moonshot-0.4.6.dist-info/RECORD,,
@@ -19,8 +19,33 @@ from moonshot.api import (
19
19
  api_update_cookbook,
20
20
  )
21
21
  from moonshot.integrations.cli.benchmark.recipe import (
22
- display_view_grading_scale_format,
23
- display_view_statistics_format,
22
+ _display_view_grading_scale_format,
23
+ _display_view_statistics_format,
24
+ )
25
+ from moonshot.integrations.cli.cli_errors import (
26
+ ERROR_BENCHMARK_ADD_COOKBOOK_DESC_VALIDATION,
27
+ ERROR_BENCHMARK_ADD_COOKBOOK_NAME_VALIDATION,
28
+ ERROR_BENCHMARK_ADD_COOKBOOK_RECIPES_LIST_STR_VALIDATION,
29
+ ERROR_BENCHMARK_ADD_COOKBOOK_RECIPES_VALIDATION,
30
+ ERROR_BENCHMARK_DELETE_COOKBOOK_COOKBOOK_VALIDATION,
31
+ ERROR_BENCHMARK_LIST_COOKBOOK_FIND_VALIDATION,
32
+ ERROR_BENCHMARK_LIST_COOKBOOK_PAGINATION_VALIDATION,
33
+ ERROR_BENCHMARK_LIST_COOKBOOK_PAGINATION_VALIDATION_1,
34
+ ERROR_BENCHMARK_RUN_COOKBOOK_COOKBOOKS_VALIDATION,
35
+ ERROR_BENCHMARK_RUN_COOKBOOK_COOKBOOKS_VALIDATION_1,
36
+ ERROR_BENCHMARK_RUN_COOKBOOK_ENDPOINTS_VALIDATION,
37
+ ERROR_BENCHMARK_RUN_COOKBOOK_ENDPOINTS_VALIDATION_1,
38
+ ERROR_BENCHMARK_RUN_COOKBOOK_NAME_VALIDATION,
39
+ ERROR_BENCHMARK_RUN_COOKBOOK_NO_RESULT,
40
+ ERROR_BENCHMARK_RUN_COOKBOOK_NUM_OF_PROMPTS_VALIDATION,
41
+ ERROR_BENCHMARK_RUN_COOKBOOK_RANDOM_SEED_VALIDATION,
42
+ ERROR_BENCHMARK_RUN_COOKBOOK_RESULT_PROC_MOD_VALIDATION,
43
+ ERROR_BENCHMARK_RUN_COOKBOOK_RUNNER_PROC_MOD_VALIDATION,
44
+ ERROR_BENCHMARK_RUN_COOKBOOK_SYS_PROMPT_VALIDATION,
45
+ ERROR_BENCHMARK_UPDATE_COOKBOOK_COOKBOOK_VALIDATION,
46
+ ERROR_BENCHMARK_UPDATE_COOKBOOK_UPDATE_VALUES_VALIDATION,
47
+ ERROR_BENCHMARK_UPDATE_COOKBOOK_UPDATE_VALUES_VALIDATION_1,
48
+ ERROR_BENCHMARK_VIEW_COOKBOOK_COOKBOOK_VALIDATION,
24
49
  )
25
50
  from moonshot.integrations.cli.common.display_helper import display_view_list_format
26
51
  from moonshot.integrations.cli.utils.process_data import filter_data
@@ -45,11 +70,38 @@ def add_cookbook(args) -> None:
45
70
  description (str): The description of the cookbook.
46
71
  recipes (str): A string representation of a list of recipes. Each recipe is represented by its ID.
47
72
 
73
+ Raises:
74
+ TypeError: If the 'name', 'description', or 'recipes' arguments are not strings or are None.
75
+ ValueError: If the 'recipes' argument is not a list after evaluation.
76
+
48
77
  Returns:
49
78
  None
50
79
  """
51
80
  try:
81
+ if not isinstance(args.name, str) or not args.name or args.name is None:
82
+ raise TypeError(ERROR_BENCHMARK_ADD_COOKBOOK_NAME_VALIDATION)
83
+
84
+ if (
85
+ not isinstance(args.description, str)
86
+ or not args.description
87
+ or args.description is None
88
+ ):
89
+ raise TypeError(ERROR_BENCHMARK_ADD_COOKBOOK_DESC_VALIDATION)
90
+
91
+ if (
92
+ not isinstance(args.recipes, str)
93
+ or not args.recipes
94
+ or args.recipes is None
95
+ ):
96
+ raise TypeError(ERROR_BENCHMARK_ADD_COOKBOOK_RECIPES_VALIDATION)
97
+
52
98
  recipes = literal_eval(args.recipes)
99
+ if not (
100
+ isinstance(recipes, list)
101
+ and all(isinstance(recipe, str) for recipe in recipes)
102
+ ):
103
+ raise ValueError(ERROR_BENCHMARK_ADD_COOKBOOK_RECIPES_LIST_STR_VALIDATION)
104
+
53
105
  new_cookbook_id = api_create_cookbook(args.name, args.description, recipes)
54
106
  print(f"[add_cookbook]: Cookbook ({new_cookbook_id}) created.")
55
107
  except Exception as e:
@@ -61,22 +113,48 @@ def list_cookbooks(args) -> list | None:
61
113
  List all available cookbooks.
62
114
 
63
115
  This function retrieves all available cookbooks by calling the api_get_all_cookbook function from the
64
- moonshot.api module.
65
- It then displays the retrieved cookbooks using the _display_cookbooks function.
116
+ moonshot.api module. It then filters the retrieved cookbooks based on the provided 'find' keyword and
117
+ 'pagination' parameters, and displays the filtered cookbooks using the _display_cookbooks function.
66
118
 
67
119
  Args:
68
- args: A namespace object from argparse. It should have an optional attribute:
69
- find (str): Optional field to find cookbook(s) with a keyword.
70
- pagination (str): Optional field to paginate cookbooks.
120
+ args: A namespace object from argparse. It should have the following optional attributes:
121
+ find (str): Optional field to find cookbook(s) with a keyword.
122
+ pagination (str): Optional field to paginate cookbooks. It should be a string representation of a tuple
123
+ containing two integers (page number and page size).
124
+
125
+ Raises:
126
+ TypeError: If the 'find' or 'pagination' arguments are not strings or are None.
127
+ ValueError: If the 'pagination' argument is not a tuple of two integers after evaluation.
71
128
 
72
129
  Returns:
73
- list | None: A list of Cookbook or None if there is no result.
130
+ list | None: A list of filtered cookbooks or None if there is no result.
74
131
  """
75
132
 
76
133
  try:
134
+ if args.find is not None:
135
+ if not isinstance(args.find, str) or not args.find:
136
+ raise TypeError(ERROR_BENCHMARK_LIST_COOKBOOK_FIND_VALIDATION)
137
+
138
+ if args.pagination is not None:
139
+ if not isinstance(args.pagination, str) or not args.pagination:
140
+ raise TypeError(ERROR_BENCHMARK_LIST_COOKBOOK_PAGINATION_VALIDATION)
141
+ try:
142
+ pagination = literal_eval(args.pagination)
143
+ if not (
144
+ isinstance(pagination, tuple)
145
+ and len(pagination) == 2
146
+ and all(isinstance(i, int) for i in pagination)
147
+ ):
148
+ raise ValueError(
149
+ ERROR_BENCHMARK_LIST_COOKBOOK_PAGINATION_VALIDATION_1
150
+ )
151
+ except (ValueError, SyntaxError):
152
+ raise ValueError(ERROR_BENCHMARK_LIST_COOKBOOK_PAGINATION_VALIDATION_1)
153
+ else:
154
+ pagination = ()
155
+
77
156
  cookbooks_list = api_get_all_cookbook()
78
157
  keyword = args.find.lower() if args.find else ""
79
- pagination = literal_eval(args.pagination) if args.pagination else ()
80
158
 
81
159
  if cookbooks_list:
82
160
  filtered_cookbooks_list = filter_data(cookbooks_list, keyword, pagination)
@@ -89,6 +167,7 @@ def list_cookbooks(args) -> list | None:
89
167
 
90
168
  except Exception as e:
91
169
  print(f"[list_cookbooks]: {str(e)}")
170
+ return None
92
171
 
93
172
 
94
173
  def view_cookbook(args) -> None:
@@ -96,19 +175,30 @@ def view_cookbook(args) -> None:
96
175
  View a specific cookbook.
97
176
 
98
177
  This function retrieves a specific cookbook by calling the api_read_cookbook function from the
99
- moonshot.api module using the cookbook name provided in the args.
178
+ moonshot.api module using the cookbook ID provided in the args.
100
179
  It then displays the retrieved cookbook using the display_view_cookbook function.
101
180
 
102
181
  Args:
103
182
  args: A namespace object from argparse. It should have the following attribute:
104
- cookbook (str): The id of the cookbook to view.
183
+ cookbook (str): The ID of the cookbook to view.
184
+
185
+ Raises:
186
+ TypeError: If the 'cookbook' argument is not a string or is None.
105
187
 
106
188
  Returns:
107
189
  None
108
190
  """
109
191
  try:
192
+ if (
193
+ not isinstance(args.cookbook, str)
194
+ or not args.cookbook
195
+ or args.cookbook is None
196
+ ):
197
+ raise TypeError(ERROR_BENCHMARK_VIEW_COOKBOOK_COOKBOOK_VALIDATION)
198
+
110
199
  cookbook_info = api_read_cookbook(args.cookbook)
111
- display_view_cookbook(cookbook_info)
200
+ _display_view_cookbook(cookbook_info)
201
+
112
202
  except Exception as e:
113
203
  print(f"[view_cookbook]: {str(e)}")
114
204
 
@@ -132,48 +222,105 @@ def run_cookbook(args) -> None:
132
222
  runner_proc_module (str): The runner processing module to use.
133
223
  result_proc_module (str): The result processing module to use.
134
224
 
225
+ Raises:
226
+ TypeError: If any of the required arguments are not of the expected type or are None.
227
+ ValueError: If the 'cookbooks' or 'endpoints' arguments are not lists of strings after evaluation.
228
+ RuntimeError: If no results are found after running the cookbooks.
229
+
135
230
  Returns:
136
231
  None
137
232
  """
138
233
  try:
139
- name = args.name
234
+ if not isinstance(args.name, str) or not args.name or args.name is None:
235
+ raise TypeError(ERROR_BENCHMARK_RUN_COOKBOOK_NAME_VALIDATION)
236
+
237
+ if (
238
+ not isinstance(args.cookbooks, str)
239
+ or not args.cookbooks
240
+ or args.cookbooks is None
241
+ ):
242
+ raise TypeError(ERROR_BENCHMARK_RUN_COOKBOOK_COOKBOOKS_VALIDATION)
243
+
244
+ if (
245
+ not isinstance(args.endpoints, str)
246
+ or not args.endpoints
247
+ or args.endpoints is None
248
+ ):
249
+ raise TypeError(ERROR_BENCHMARK_RUN_COOKBOOK_ENDPOINTS_VALIDATION)
250
+
251
+ if isinstance(args.num_of_prompts, bool) or not isinstance(
252
+ args.num_of_prompts, int
253
+ ):
254
+ raise TypeError(ERROR_BENCHMARK_RUN_COOKBOOK_NUM_OF_PROMPTS_VALIDATION)
255
+
256
+ if isinstance(args.random_seed, bool) or not isinstance(args.random_seed, int):
257
+ raise TypeError(ERROR_BENCHMARK_RUN_COOKBOOK_RANDOM_SEED_VALIDATION)
258
+
259
+ if (
260
+ not isinstance(args.system_prompt, str)
261
+ or not args.system_prompt
262
+ or args.system_prompt is None
263
+ ):
264
+ raise TypeError(ERROR_BENCHMARK_RUN_COOKBOOK_SYS_PROMPT_VALIDATION)
265
+
266
+ if (
267
+ not isinstance(args.runner_proc_module, str)
268
+ or not args.runner_proc_module
269
+ or args.runner_proc_module is None
270
+ ):
271
+ raise TypeError(ERROR_BENCHMARK_RUN_COOKBOOK_RUNNER_PROC_MOD_VALIDATION)
272
+
273
+ if (
274
+ not isinstance(args.result_proc_module, str)
275
+ or not args.result_proc_module
276
+ or args.result_proc_module is None
277
+ ):
278
+ raise TypeError(ERROR_BENCHMARK_RUN_COOKBOOK_RESULT_PROC_MOD_VALIDATION)
279
+
140
280
  cookbooks = literal_eval(args.cookbooks)
281
+ if not (
282
+ isinstance(cookbooks, list)
283
+ and all(isinstance(item, str) for item in cookbooks)
284
+ ):
285
+ raise TypeError(ERROR_BENCHMARK_RUN_COOKBOOK_COOKBOOKS_VALIDATION_1)
286
+
141
287
  endpoints = literal_eval(args.endpoints)
142
- num_of_prompts = args.num_of_prompts
143
- random_seed = args.random_seed
144
- system_prompt = args.system_prompt
145
- runner_proc_module = args.runner_proc_module
146
- result_proc_module = args.result_proc_module
288
+ if not (
289
+ isinstance(endpoints, list)
290
+ and all(isinstance(item, str) for item in endpoints)
291
+ ):
292
+ raise TypeError(ERROR_BENCHMARK_RUN_COOKBOOK_ENDPOINTS_VALIDATION_1)
147
293
 
148
294
  # Run the cookbooks with the defined endpoints
149
- slugify_id = slugify(name, lowercase=True)
295
+ slugify_id = slugify(args.name, lowercase=True)
150
296
  if slugify_id in api_get_all_runner_name():
151
297
  cb_runner = api_load_runner(slugify_id)
152
298
  else:
153
- cb_runner = api_create_runner(name, endpoints)
299
+ cb_runner = api_create_runner(args.name, endpoints)
154
300
 
155
- loop = asyncio.get_event_loop()
156
- loop.run_until_complete(
157
- cb_runner.run_cookbooks(
301
+ async def run():
302
+ await cb_runner.run_cookbooks(
158
303
  cookbooks,
159
- num_of_prompts,
160
- random_seed,
161
- system_prompt,
162
- runner_proc_module,
163
- result_proc_module,
304
+ args.num_of_prompts,
305
+ args.random_seed,
306
+ args.system_prompt,
307
+ args.runner_proc_module,
308
+ args.result_proc_module,
164
309
  )
165
- )
166
- cb_runner.close()
310
+ await cb_runner.close()
311
+
312
+ loop = asyncio.get_event_loop()
313
+ loop.run_until_complete(run())
167
314
 
168
315
  # Display results
169
316
  runner_runs = api_get_all_run(cb_runner.id)
170
317
  result_info = runner_runs[-1].get("results")
171
318
  if result_info:
172
- show_cookbook_results(
319
+ _show_cookbook_results(
173
320
  cookbooks, endpoints, result_info, result_info["metadata"]["duration"]
174
321
  )
175
322
  else:
176
- raise RuntimeError("no run result generated")
323
+ raise RuntimeError(ERROR_BENCHMARK_RUN_COOKBOOK_NO_RESULT)
177
324
 
178
325
  except Exception as e:
179
326
  print(f"[run_cookbook]: {str(e)}")
@@ -183,8 +330,8 @@ def update_cookbook(args) -> None:
183
330
  """
184
331
  Update a specific cookbook.
185
332
 
186
- This function updates a specific cookbook by calling the api_update_cookbook function from the
187
- moonshot.api module using the cookbook name and update values provided in the args.
333
+ This function updates a specific cookbook by calling the api_update_cookbook function using the
334
+ cookbook name and update values provided in the args.
188
335
 
189
336
  Args:
190
337
  args: A namespace object from argparse. It should have the following attributes:
@@ -192,13 +339,36 @@ def update_cookbook(args) -> None:
192
339
  update_values (str): A string representation of a list of tuples. Each tuple contains a key
193
340
  and a value to update in the cookbook.
194
341
 
342
+ Raises:
343
+ ValueError: If the 'cookbook' or 'update_values' arguments are not of the expected type or are None.
344
+
195
345
  Returns:
196
346
  None
197
347
  """
198
348
  try:
349
+ if (
350
+ args.cookbook is None
351
+ or not isinstance(args.cookbook, str)
352
+ or not args.cookbook
353
+ ):
354
+ raise ValueError(ERROR_BENCHMARK_UPDATE_COOKBOOK_COOKBOOK_VALIDATION)
355
+
356
+ if (
357
+ args.update_values is None
358
+ or not isinstance(args.update_values, str)
359
+ or not args.update_values
360
+ ):
361
+ raise ValueError(ERROR_BENCHMARK_UPDATE_COOKBOOK_UPDATE_VALUES_VALIDATION)
362
+
199
363
  cookbook = args.cookbook
200
- update_values = dict(literal_eval(args.update_values))
364
+ if literal_eval(args.update_values) and all(
365
+ isinstance(i, tuple) for i in literal_eval(args.update_values)
366
+ ):
367
+ update_values = dict(literal_eval(args.update_values))
368
+ else:
369
+ raise ValueError(ERROR_BENCHMARK_UPDATE_COOKBOOK_UPDATE_VALUES_VALIDATION_1)
201
370
  api_update_cookbook(cookbook, **update_values)
371
+
202
372
  print("[update_cookbook]: Cookbook updated.")
203
373
  except Exception as e:
204
374
  print(f"[update_cookbook]: {str(e)}")
@@ -218,6 +388,9 @@ def delete_cookbook(args) -> None:
218
388
  args: A namespace object from argparse. It should have the following attribute:
219
389
  cookbook (str): The identifier of the cookbook to delete.
220
390
 
391
+ Raises:
392
+ ValueError: If the 'cookbook' argument is not a string or is None.
393
+
221
394
  Returns:
222
395
  None
223
396
  """
@@ -228,7 +401,15 @@ def delete_cookbook(args) -> None:
228
401
  if confirmation.lower() != "y":
229
402
  console.print("[bold yellow]Cookbook deletion cancelled.[/]")
230
403
  return
404
+
231
405
  try:
406
+ if (
407
+ args.cookbook is None
408
+ or not isinstance(args.cookbook, str)
409
+ or not args.cookbook
410
+ ):
411
+ raise ValueError(ERROR_BENCHMARK_DELETE_COOKBOOK_COOKBOOK_VALIDATION)
412
+
232
413
  api_delete_cookbook(args.cookbook)
233
414
  print("[delete_cookbook]: Cookbook deleted.")
234
415
  except Exception as e:
@@ -248,6 +429,9 @@ def _display_cookbooks(cookbooks_list):
248
429
 
249
430
  Args:
250
431
  cookbooks_list (list): A list of dictionaries, where each dictionary contains the details of a cookbook.
432
+
433
+ Returns:
434
+ None
251
435
  """
252
436
  table = Table(
253
437
  title="List of Cookbooks", show_lines=True, expand=True, header_style="bold"
@@ -265,7 +449,7 @@ def _display_cookbooks(cookbooks_list):
265
449
  console.print(table)
266
450
 
267
451
 
268
- def display_view_cookbook(cookbook_info):
452
+ def _display_view_cookbook(cookbook_info):
269
453
  """
270
454
  Display the cookbook information in a formatted table.
271
455
 
@@ -313,10 +497,10 @@ def display_view_cookbook(cookbook_info):
313
497
  attack_strategies_info = display_view_list_format(
314
498
  "Attack Strategies", attack_strategies
315
499
  )
316
- grading_scale_info = display_view_grading_scale_format(
500
+ grading_scale_info = _display_view_grading_scale_format(
317
501
  "Grading Scale", grading_scale
318
502
  )
319
- stats_info = display_view_statistics_format("Statistics", stats)
503
+ stats_info = _display_view_statistics_format("Statistics", stats)
320
504
 
321
505
  recipe_info = (
322
506
  f"[red]id: {id}[/red]\n\n[blue]{name}[/blue]\n{description}\n\n"
@@ -331,11 +515,11 @@ def display_view_cookbook(cookbook_info):
331
515
  console.print("[red]There are no recipes found for the cookbook.[/red]")
332
516
 
333
517
 
334
- def show_cookbook_results(cookbooks, endpoints, cookbook_results, duration):
518
+ def _show_cookbook_results(cookbooks, endpoints, cookbook_results, duration):
335
519
  """
336
520
  Show the results of the cookbook benchmarking.
337
521
 
338
- This function takes the cookbooks, endpoints, cookbook results, results file, and duration as arguments.
522
+ This function takes the cookbooks, endpoints, cookbook results, and duration as arguments.
339
523
  If there are results, it generates a table with the cookbook results and prints a message indicating
340
524
  where the results are saved. If there are no results, it prints a message indicating that no results were found.
341
525
  Finally, it prints the duration of the run.
@@ -351,7 +535,7 @@ def show_cookbook_results(cookbooks, endpoints, cookbook_results, duration):
351
535
  """
352
536
  if cookbook_results:
353
537
  # Display recipe results
354
- generate_cookbook_table(cookbooks, endpoints, cookbook_results)
538
+ _generate_cookbook_table(cookbooks, endpoints, cookbook_results)
355
539
  else:
356
540
  console.print("[red]There are no results.[/red]")
357
541
 
@@ -361,7 +545,7 @@ def show_cookbook_results(cookbooks, endpoints, cookbook_results, duration):
361
545
  console.print(run_stats)
362
546
 
363
547
 
364
- def generate_cookbook_table(cookbooks: list, endpoints: list, results: dict) -> None:
548
+ def _generate_cookbook_table(cookbooks: list, endpoints: list, results: dict) -> None:
365
549
  """
366
550
  Generate and display a table with the cookbook benchmarking results.
367
551
 
@@ -9,6 +9,13 @@ from moonshot.api import (
9
9
  api_get_all_datasets,
10
10
  api_get_all_datasets_name,
11
11
  )
12
+ from moonshot.integrations.cli.cli_errors import (
13
+ ERROR_BENCHMARK_DELETE_DATASET_DATASET_VALIDATION,
14
+ ERROR_BENCHMARK_LIST_DATASETS_FIND_VALIDATION,
15
+ ERROR_BENCHMARK_LIST_DATASETS_PAGINATION_VALIDATION,
16
+ ERROR_BENCHMARK_LIST_DATASETS_PAGINATION_VALIDATION_1,
17
+ ERROR_BENCHMARK_VIEW_DATASET_DATASET_FILENAME_VALIDATION,
18
+ )
12
19
  from moonshot.integrations.cli.common.display_helper import display_view_str_format
13
20
  from moonshot.integrations.cli.utils.process_data import filter_data
14
21
 
@@ -23,22 +30,43 @@ def list_datasets(args) -> list | None:
23
30
  List all available datasets.
24
31
 
25
32
  This function retrieves all available datasets by calling the api_get_all_datasets function from the
26
- moonshot.api module. It then displays the datasets using the _display_datasets function. If an exception occurs,
27
- it prints an error message.
33
+ moonshot.api module. It then filters the datasets based on the provided keyword and pagination arguments.
34
+ If there are no datasets, it prints a message indicating that no datasets were found.
28
35
 
29
36
  Args:
30
- args: A namespace object from argparse. It should have an optional attribute:
31
- find (str): Optional field to find dataset(s) with a keyword.
32
- pagination (str): Optional field to paginate datasets.
37
+ args: A namespace object from argparse. It should have optional attributes:
38
+ find (str): Optional keyword to filter datasets.
39
+ pagination (str): Optional tuple to paginate datasets.
33
40
 
34
41
  Returns:
35
- list | None: A list of Dataset or None if there is no result.
42
+ list | None: A list of datasets or None if there are no datasets.
36
43
  """
37
44
  try:
38
45
  print("Listing datasets may take a while...")
46
+ if args.find is not None:
47
+ if not isinstance(args.find, str) or not args.find:
48
+ raise TypeError(ERROR_BENCHMARK_LIST_DATASETS_FIND_VALIDATION)
49
+
50
+ if args.pagination is not None:
51
+ if not isinstance(args.pagination, str) or not args.pagination:
52
+ raise TypeError(ERROR_BENCHMARK_LIST_DATASETS_PAGINATION_VALIDATION)
53
+ try:
54
+ pagination = literal_eval(args.pagination)
55
+ if not (
56
+ isinstance(pagination, tuple)
57
+ and len(pagination) == 2
58
+ and all(isinstance(i, int) for i in pagination)
59
+ ):
60
+ raise ValueError(
61
+ ERROR_BENCHMARK_LIST_DATASETS_PAGINATION_VALIDATION_1
62
+ )
63
+ except (ValueError, SyntaxError):
64
+ raise ValueError(ERROR_BENCHMARK_LIST_DATASETS_PAGINATION_VALIDATION_1)
65
+ else:
66
+ pagination = ()
67
+
39
68
  datasets_list = api_get_all_datasets()
40
69
  keyword = args.find.lower() if args.find else ""
41
- pagination = literal_eval(args.pagination) if args.pagination else ()
42
70
 
43
71
  if datasets_list:
44
72
  filtered_datasets_list = filter_data(datasets_list, keyword, pagination)
@@ -48,8 +76,10 @@ def list_datasets(args) -> list | None:
48
76
 
49
77
  console.print("[red]There are no datasets found.[/red]")
50
78
  return None
79
+
51
80
  except Exception as e:
52
81
  print(f"[list_datasets]: {str(e)}")
82
+ return None
53
83
 
54
84
 
55
85
  def view_dataset(args) -> None:
@@ -69,6 +99,13 @@ def view_dataset(args) -> None:
69
99
  """
70
100
  try:
71
101
  print("Viewing datasets may take a while...")
102
+ if (
103
+ not isinstance(args.dataset_filename, str)
104
+ or not args.dataset_filename
105
+ or args.dataset_filename is None
106
+ ):
107
+ raise TypeError(ERROR_BENCHMARK_VIEW_DATASET_DATASET_FILENAME_VALIDATION)
108
+
72
109
  datasets_list = api_get_all_datasets()
73
110
  datasets_name_list = api_get_all_datasets_name()
74
111
 
@@ -92,7 +129,7 @@ def delete_dataset(args) -> None:
92
129
 
93
130
  Args:
94
131
  args: A namespace object from argparse. It should have the following attribute:
95
- dataset_name (str): The name of the dataset to delete.
132
+ dataset (str): The name of the dataset to delete.
96
133
 
97
134
  Returns:
98
135
  None
@@ -104,7 +141,15 @@ def delete_dataset(args) -> None:
104
141
  if confirmation.lower() != "y":
105
142
  console.print("[bold yellow]Dataset deletion cancelled.[/]")
106
143
  return
144
+
107
145
  try:
146
+ if (
147
+ args.dataset is None
148
+ or not isinstance(args.dataset, str)
149
+ or not args.dataset
150
+ ):
151
+ raise ValueError(ERROR_BENCHMARK_DELETE_DATASET_DATASET_VALIDATION)
152
+
108
153
  api_delete_dataset(args.dataset)
109
154
  print("[delete_dataset]: Dataset deleted.")
110
155
  except Exception as e: