aiverify-moonshot 0.4.10__py3-none-any.whl → 0.5.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.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/METADATA +24 -26
- {aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/RECORD +37 -36
- {aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/WHEEL +1 -1
- moonshot/integrations/cli/benchmark/cookbook.py +8 -11
- moonshot/integrations/cli/benchmark/recipe.py +1 -5
- moonshot/integrations/cli/cli_errors.py +3 -0
- moonshot/integrations/cli/common/connectors.py +22 -10
- moonshot/integrations/web_api/app.py +1 -1
- moonshot/integrations/web_api/schemas/endpoint_create_dto.py +1 -0
- moonshot/integrations/web_api/services/endpoint_service.py +1 -0
- moonshot/src/api/api_bookmark.py +16 -5
- moonshot/src/api/api_connector.py +3 -3
- moonshot/src/api/api_connector_endpoint.py +6 -3
- moonshot/src/api/api_context_strategy.py +2 -2
- moonshot/src/api/api_cookbook.py +6 -6
- moonshot/src/api/api_dataset.py +5 -5
- moonshot/src/api/api_environment_variables.py +3 -0
- moonshot/src/api/api_metrics.py +1 -1
- moonshot/src/api/api_prompt_template.py +9 -0
- moonshot/src/api/api_recipe.py +3 -3
- moonshot/src/api/api_red_teaming.py +4 -8
- moonshot/src/api/api_result.py +10 -6
- moonshot/src/api/api_run.py +3 -3
- moonshot/src/api/api_runner.py +7 -6
- moonshot/src/api/api_session.py +11 -7
- moonshot/src/bookmark/bookmark.py +12 -5
- moonshot/src/connectors/connector.py +127 -62
- moonshot/src/connectors/connector_prompt_arguments.py +15 -5
- moonshot/src/connectors/connector_response.py +15 -0
- moonshot/src/connectors_endpoints/connector_endpoint.py +32 -20
- moonshot/src/connectors_endpoints/connector_endpoint_arguments.py +4 -1
- moonshot/src/messages_constants.py +85 -3
- moonshot/src/redteaming/attack/attack_module.py +34 -7
- moonshot/src/runs/run_arguments.py +43 -20
- {aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/licenses/AUTHORS.md +0 -0
- {aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/licenses/LICENSE.md +0 -0
- {aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/licenses/NOTICES.md +0 -0
|
@@ -15,7 +15,9 @@ BOOKMARK_GET_BOOKMARK_ERROR_1 = "[Bookmark] Invalid bookmark name: {message}"
|
|
|
15
15
|
# BOOKMARK - delete_bookmark
|
|
16
16
|
# ------------------------------------------------------------------------------
|
|
17
17
|
BOOKMARK_DELETE_BOOKMARK_SUCCESS = "[Bookmark] Bookmark record deleted."
|
|
18
|
-
BOOKMARK_DELETE_BOOKMARK_FAIL =
|
|
18
|
+
BOOKMARK_DELETE_BOOKMARK_FAIL = (
|
|
19
|
+
"[Bookmark] Bookmark record not found. Unable to delete."
|
|
20
|
+
)
|
|
19
21
|
BOOKMARK_DELETE_BOOKMARK_ERROR = (
|
|
20
22
|
"[Bookmark] Failed to delete bookmark record: {message}"
|
|
21
23
|
)
|
|
@@ -33,9 +35,89 @@ BOOKMARK_DELETE_ALL_BOOKMARK_ERROR = (
|
|
|
33
35
|
# BOOKMARK - export_bookmarks
|
|
34
36
|
# ------------------------------------------------------------------------------
|
|
35
37
|
BOOKMARK_EXPORT_BOOKMARK_ERROR = "[Bookmark] Failed to export bookmarks: {message}"
|
|
36
|
-
BOOKMARK_EXPORT_BOOKMARK_VALIDATION_ERROR =
|
|
38
|
+
BOOKMARK_EXPORT_BOOKMARK_VALIDATION_ERROR = (
|
|
39
|
+
"Export filename must be a non-empty string."
|
|
40
|
+
)
|
|
37
41
|
|
|
38
42
|
# ------------------------------------------------------------------------------
|
|
39
43
|
# BOOKMARK ARGUMENTS - from_tuple_to_dict
|
|
40
44
|
# ------------------------------------------------------------------------------
|
|
41
|
-
BOOKMARK_ARGUMENTS_FROM_TUPLE_TO_DICT_VALIDATION_ERROR = "[BookmarkArguments] Failed to convert to dictionary because of the insufficient number of values" # noqa: E501
|
|
45
|
+
BOOKMARK_ARGUMENTS_FROM_TUPLE_TO_DICT_VALIDATION_ERROR = "[BookmarkArguments] Failed to convert to dictionary because of the insufficient number of values." # noqa: E501
|
|
46
|
+
|
|
47
|
+
# ------------------------------------------------------------------------------
|
|
48
|
+
# CONNECTOR - perform_retry_callback
|
|
49
|
+
# ------------------------------------------------------------------------------
|
|
50
|
+
CONNECTOR_PERFORM_RETRY_CALLBACK_ERROR = "[Connector ID: {connector_id}] Attempt {attempt_no} failed due to error: {message}" # noqa: E501
|
|
51
|
+
|
|
52
|
+
# ------------------------------------------------------------------------------
|
|
53
|
+
# CONNECTOR - load
|
|
54
|
+
# ------------------------------------------------------------------------------
|
|
55
|
+
CONNECTOR_LOAD_CONNECTOR_ENDPOINT_ARGUMENTS_VALIDATION_ERROR = "[Connector] The 'ep_args' argument must be an instance of ConnectorEndpointArguments and not None." # noqa: E501
|
|
56
|
+
CONNECTOR_LOAD_CONNECTOR_INSTANCE_RUNTIME_ERROR = (
|
|
57
|
+
"[Connector] Failed to get connector instance: {message}"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# ------------------------------------------------------------------------------
|
|
61
|
+
# CONNECTOR - create
|
|
62
|
+
# ------------------------------------------------------------------------------
|
|
63
|
+
CONNECTOR_CREATE_CONNECTOR_ENDPOINT_ARGUMENTS_VALIDATION_ERROR = "[Connector] The 'ep_args' argument must be an instance of ConnectorEndpointArguments and not None." # noqa: E501
|
|
64
|
+
CONNECTOR_CREATE_ERROR = "[Connector] Failed to create connector: {message}"
|
|
65
|
+
|
|
66
|
+
# ------------------------------------------------------------------------------
|
|
67
|
+
# CONNECTOR - get_available_items
|
|
68
|
+
# ------------------------------------------------------------------------------
|
|
69
|
+
CONNECTOR_GET_AVAILABLE_ITEMS_ERROR = (
|
|
70
|
+
"[Connector] Failed to get available connectors: {message}"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# ------------------------------------------------------------------------------
|
|
74
|
+
# CONNECTOR - get_prediction
|
|
75
|
+
# ------------------------------------------------------------------------------
|
|
76
|
+
CONNECTOR_GET_PREDICTION_ARGUMENTS_GENERATED_PROMPT_VALIDATION_ERROR = "[Connector] The 'generated_prompt' argument must be an instance of ConnectorPromptArguments and not None." # noqa: E501
|
|
77
|
+
CONNECTOR_GET_PREDICTION_ARGUMENTS_CONNECTOR_VALIDATION_ERROR = "[Connector] The 'connector' argument must be an instance of Connector and not None." # noqa: E501
|
|
78
|
+
CONNECTOR_GET_PREDICTION_INFO = (
|
|
79
|
+
"[Connector ID: {connector_id}] Predicting Prompt Index {prompt_index}."
|
|
80
|
+
)
|
|
81
|
+
CONNECTOR_GET_PREDICTION_TIME_TAKEN_INFO = "[Connector ID: {connector_id}] Prompt Index {prompt_index} took {prompt_duration}s." # noqa: E501
|
|
82
|
+
CONNECTOR_GET_PREDICTION_ERROR = "[Connector ID: {connector_id}] Prompt Index {prompt_index} failed to get prediction: {message}" # noqa: E501
|
|
83
|
+
|
|
84
|
+
# ------------------------------------------------------------------------------
|
|
85
|
+
# CONNECTOR - set_system_prompt
|
|
86
|
+
# ------------------------------------------------------------------------------
|
|
87
|
+
CONNECTOR_SET_SYSTEM_PROMPT_VALIDATION_ERROR = "[Connector] The 'system_prompt' argument must be an instance of string and not None." # noqa: E501
|
|
88
|
+
|
|
89
|
+
# ------------------------------------------------------------------------------
|
|
90
|
+
# CONNECTOR ENDPOINT - create
|
|
91
|
+
# ------------------------------------------------------------------------------
|
|
92
|
+
CONNECTOR_ENDPOINT_CREATE_ERROR = (
|
|
93
|
+
"[ConnectorEndpoint] Failed to create connector endpoint: {message}"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# ------------------------------------------------------------------------------
|
|
97
|
+
# CONNECTOR ENDPOINT - read
|
|
98
|
+
# ------------------------------------------------------------------------------
|
|
99
|
+
CONNECTOR_ENDPOINT_READ_INVALID = "Invalid connector endpoint id - {ep_id}"
|
|
100
|
+
CONNECTOR_ENDPOINT_READ_ERROR = (
|
|
101
|
+
"[ConnectorEndpoint] Failed to read connector endpoint: {message}"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# ------------------------------------------------------------------------------
|
|
105
|
+
# CONNECTOR ENDPOINT - update
|
|
106
|
+
# ------------------------------------------------------------------------------
|
|
107
|
+
CONNECTOR_ENDPOINT_UPDATE_ERROR = (
|
|
108
|
+
"[ConnectorEndpoint] Failed to update connector endpoint: {message}"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# ------------------------------------------------------------------------------
|
|
112
|
+
# CONNECTOR ENDPOINT - delete
|
|
113
|
+
# ------------------------------------------------------------------------------
|
|
114
|
+
CONNECTOR_ENDPOINT_DELETE_ERROR = (
|
|
115
|
+
"[ConnectorEndpoint] Failed to delete connector endpoint: {message}"
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# ------------------------------------------------------------------------------
|
|
119
|
+
# CONNECTOR ENDPOINT - get_available_items
|
|
120
|
+
# ------------------------------------------------------------------------------
|
|
121
|
+
CONNECTOR_ENDPOINT_GET_AVAILABLE_ITEMS_ERROR = (
|
|
122
|
+
"[ConnectorEndpoint] Failed to get available connector endpoints: {message}"
|
|
123
|
+
)
|
|
@@ -31,6 +31,22 @@ class AttackModule:
|
|
|
31
31
|
INSERT INTO {} (connection_id,context_strategy,prompt_template,attack_module,
|
|
32
32
|
metric,prompt,prepared_prompt,system_prompt,predicted_result,duration,prompt_time)VALUES(?,?,?,?,?,?,?,?,?,?,?)
|
|
33
33
|
"""
|
|
34
|
+
sql_create_chat_history_table = """
|
|
35
|
+
CREATE TABLE IF NOT EXISTS {} (
|
|
36
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
37
|
+
connection_id text NOT NULL,
|
|
38
|
+
context_strategy text,
|
|
39
|
+
prompt_template text,
|
|
40
|
+
attack_module text,
|
|
41
|
+
metric text,
|
|
42
|
+
prompt text NOT NULL,
|
|
43
|
+
prepared_prompt text NOT NULL,
|
|
44
|
+
system_prompt text,
|
|
45
|
+
predicted_result text NOT NULL,
|
|
46
|
+
duration text NOT NULL,
|
|
47
|
+
prompt_time text NOT NULL
|
|
48
|
+
);
|
|
49
|
+
"""
|
|
34
50
|
|
|
35
51
|
def __init__(self, am_id: str, am_arguments: AttackModuleArguments | None = None):
|
|
36
52
|
self.id = am_id
|
|
@@ -261,6 +277,15 @@ class AttackModule:
|
|
|
261
277
|
list: A list of consolidated responses from the specified LLM connector.
|
|
262
278
|
"""
|
|
263
279
|
consolidated_responses = []
|
|
280
|
+
|
|
281
|
+
# perform a check to see if the target endpoint has its table in the db. if not, create one
|
|
282
|
+
endpoint_id = target_llm_connector.id.replace("-", "_")
|
|
283
|
+
if not Storage.check_database_table_exists(self.db_instance, endpoint_id):
|
|
284
|
+
Storage.create_database_table(
|
|
285
|
+
self.db_instance,
|
|
286
|
+
AttackModule.sql_create_chat_history_table.format(endpoint_id),
|
|
287
|
+
)
|
|
288
|
+
|
|
264
289
|
for prepared_prompt in list_of_prompts:
|
|
265
290
|
if self.cancel_event.is_set():
|
|
266
291
|
logger.warning(
|
|
@@ -316,6 +341,7 @@ class AttackModule:
|
|
|
316
341
|
chat_record_tuple (tuple): A tuple containing the chat record information.
|
|
317
342
|
chat_record_id (str): The ID of the chat record.
|
|
318
343
|
"""
|
|
344
|
+
|
|
319
345
|
endpoint_id = chat_record_id.replace("-", "_")
|
|
320
346
|
Storage.create_database_record(
|
|
321
347
|
self.db_instance,
|
|
@@ -623,7 +649,8 @@ class RedTeamingPromptArguments(BaseModel):
|
|
|
623
649
|
|
|
624
650
|
This method collects all the attributes of the RedTeamingPromptArguments instance and forms a tuple
|
|
625
651
|
with the attribute values in this specific order: conn_id, cs_id, pt_id, am_id, me_id, original_prompt,
|
|
626
|
-
connector_prompt.prompt,
|
|
652
|
+
connector_prompt.prompt, system_prompt, connector_prompt.predicted_results.response,
|
|
653
|
+
connector_prompt.duration, start_time.
|
|
627
654
|
|
|
628
655
|
Returns:
|
|
629
656
|
tuple: A tuple representation of the RedTeamingPromptArguments instance.
|
|
@@ -637,21 +664,21 @@ class RedTeamingPromptArguments(BaseModel):
|
|
|
637
664
|
self.original_prompt,
|
|
638
665
|
self.connector_prompt.prompt,
|
|
639
666
|
self.system_prompt,
|
|
640
|
-
|
|
667
|
+
self.connector_prompt.predicted_results.response if self.connector_prompt.predicted_results else "",
|
|
641
668
|
str(self.connector_prompt.duration),
|
|
642
669
|
self.start_time,
|
|
643
670
|
)
|
|
644
671
|
|
|
645
672
|
def to_dict(self) -> dict:
|
|
646
673
|
"""
|
|
647
|
-
Converts the RedTeamingPromptArguments instance into a
|
|
674
|
+
Converts the RedTeamingPromptArguments instance into a dictionary.
|
|
648
675
|
|
|
649
|
-
This method collects all the attributes of the RedTeamingPromptArguments instance and forms a
|
|
650
|
-
with the keys: conn_id, cs_id, pt_id, am_id, me_id, original_prompt, prepared_prompt,
|
|
676
|
+
This method collects all the attributes of the RedTeamingPromptArguments instance and forms a dictionary
|
|
677
|
+
with the keys: conn_id, cs_id, pt_id, am_id, me_id, original_prompt, system_prompt, prepared_prompt,
|
|
651
678
|
response, duration, start_time.
|
|
652
679
|
|
|
653
680
|
Returns:
|
|
654
|
-
dict: A
|
|
681
|
+
dict: A dictionary representation of the RedTeamingPromptArguments instance.
|
|
655
682
|
"""
|
|
656
683
|
return {
|
|
657
684
|
"conn_id": self.conn_id,
|
|
@@ -662,7 +689,7 @@ class RedTeamingPromptArguments(BaseModel):
|
|
|
662
689
|
"original_prompt": self.original_prompt,
|
|
663
690
|
"prepared_prompt": self.connector_prompt.prompt,
|
|
664
691
|
"system_prompt": self.system_prompt,
|
|
665
|
-
"response":
|
|
692
|
+
"response": self.connector_prompt.predicted_results.response if self.connector_prompt.predicted_results else "",
|
|
666
693
|
"duration": str(self.connector_prompt.duration),
|
|
667
694
|
"start_time": self.start_time,
|
|
668
695
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import ast
|
|
4
|
+
import json
|
|
4
5
|
|
|
5
6
|
from pydantic import BaseModel
|
|
6
7
|
|
|
@@ -83,20 +84,7 @@ class RunArguments(BaseModel):
|
|
|
83
84
|
Returns:
|
|
84
85
|
tuple: A tuple containing the run arguments ready for database insertion.
|
|
85
86
|
"""
|
|
86
|
-
return (
|
|
87
|
-
self.runner_id,
|
|
88
|
-
self.runner_type.name.lower(),
|
|
89
|
-
str(self.runner_args),
|
|
90
|
-
str(self.endpoints),
|
|
91
|
-
self.results_file,
|
|
92
|
-
self.start_time,
|
|
93
|
-
self.end_time,
|
|
94
|
-
self.duration,
|
|
95
|
-
str(self.error_messages),
|
|
96
|
-
str(self.raw_results),
|
|
97
|
-
str(self.results),
|
|
98
|
-
self.status.name.lower(),
|
|
99
|
-
)
|
|
87
|
+
return self._to_tuple(include_run_id=False)
|
|
100
88
|
|
|
101
89
|
def to_tuple(self) -> tuple:
|
|
102
90
|
"""
|
|
@@ -112,7 +100,42 @@ class RunArguments(BaseModel):
|
|
|
112
100
|
Returns:
|
|
113
101
|
tuple: A tuple containing the serialized attributes of the RunArguments instance.
|
|
114
102
|
"""
|
|
115
|
-
return (
|
|
103
|
+
return self._to_tuple(include_run_id=True)
|
|
104
|
+
|
|
105
|
+
def _to_tuple(self, include_run_id: bool) -> tuple:
|
|
106
|
+
"""
|
|
107
|
+
Converts the RunArguments object to a tuple format.
|
|
108
|
+
|
|
109
|
+
This method serializes the RunArguments instance into a tuple, including or excluding the run_id based on the
|
|
110
|
+
include_run_id parameter. It ensures that all dictionary keys are converted to strings and JSON-encodes
|
|
111
|
+
the raw_results and results attributes.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
include_run_id (bool): A flag indicating whether to include the run_id in the resulting tuple.
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
tuple: A tuple containing the serialized attributes of the RunArguments instance.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
def convert_keys_to_str(d):
|
|
121
|
+
"""
|
|
122
|
+
Recursively converts all keys in a dictionary to strings.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
d (dict): The dictionary whose keys need to be converted.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
dict: A new dictionary with all keys converted to strings.
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
def convert_value(v):
|
|
132
|
+
if isinstance(v, dict):
|
|
133
|
+
return {str(k): convert_value(val) for k, val in v.items()}
|
|
134
|
+
return v
|
|
135
|
+
|
|
136
|
+
return {str(k): convert_value(v) for k, v in d.items()}
|
|
137
|
+
|
|
138
|
+
base_tuple = (
|
|
116
139
|
self.runner_id,
|
|
117
140
|
self.runner_type.name.lower(),
|
|
118
141
|
str(self.runner_args),
|
|
@@ -122,11 +145,11 @@ class RunArguments(BaseModel):
|
|
|
122
145
|
self.end_time,
|
|
123
146
|
self.duration,
|
|
124
147
|
str(self.error_messages),
|
|
125
|
-
|
|
126
|
-
|
|
148
|
+
json.dumps(convert_keys_to_str(self.raw_results)),
|
|
149
|
+
json.dumps(self.results),
|
|
127
150
|
self.status.name.lower(),
|
|
128
|
-
self.run_id,
|
|
129
151
|
)
|
|
152
|
+
return base_tuple + (self.run_id,) if include_run_id else base_tuple
|
|
130
153
|
|
|
131
154
|
@classmethod
|
|
132
155
|
def from_tuple(cls, run_record: tuple) -> RunArguments:
|
|
@@ -156,7 +179,7 @@ class RunArguments(BaseModel):
|
|
|
156
179
|
end_time=float(run_record[7]),
|
|
157
180
|
duration=run_record[8],
|
|
158
181
|
error_messages=ast.literal_eval(run_record[9]),
|
|
159
|
-
raw_results=
|
|
160
|
-
results=
|
|
182
|
+
raw_results=json.loads(run_record[10]),
|
|
183
|
+
results=json.loads(run_record[11]),
|
|
161
184
|
status=RunStatus(run_record[12]),
|
|
162
185
|
)
|
{aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/licenses/AUTHORS.md
RENAMED
|
File without changes
|
{aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/licenses/LICENSE.md
RENAMED
|
File without changes
|
{aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/licenses/NOTICES.md
RENAMED
|
File without changes
|