hackagent 0.3.1__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 (183) hide show
  1. hackagent/__init__.py +12 -0
  2. hackagent/agent.py +214 -0
  3. hackagent/api/__init__.py +1 -0
  4. hackagent/api/agent/__init__.py +1 -0
  5. hackagent/api/agent/agent_create.py +347 -0
  6. hackagent/api/agent/agent_destroy.py +140 -0
  7. hackagent/api/agent/agent_list.py +242 -0
  8. hackagent/api/agent/agent_partial_update.py +361 -0
  9. hackagent/api/agent/agent_retrieve.py +235 -0
  10. hackagent/api/agent/agent_update.py +361 -0
  11. hackagent/api/apilogs/__init__.py +1 -0
  12. hackagent/api/apilogs/apilogs_list.py +170 -0
  13. hackagent/api/apilogs/apilogs_retrieve.py +162 -0
  14. hackagent/api/attack/__init__.py +1 -0
  15. hackagent/api/attack/attack_create.py +275 -0
  16. hackagent/api/attack/attack_destroy.py +146 -0
  17. hackagent/api/attack/attack_list.py +254 -0
  18. hackagent/api/attack/attack_partial_update.py +289 -0
  19. hackagent/api/attack/attack_retrieve.py +247 -0
  20. hackagent/api/attack/attack_update.py +289 -0
  21. hackagent/api/checkout/__init__.py +1 -0
  22. hackagent/api/checkout/checkout_create.py +225 -0
  23. hackagent/api/generate/__init__.py +1 -0
  24. hackagent/api/generate/generate_create.py +253 -0
  25. hackagent/api/judge/__init__.py +1 -0
  26. hackagent/api/judge/judge_create.py +253 -0
  27. hackagent/api/key/__init__.py +1 -0
  28. hackagent/api/key/key_create.py +179 -0
  29. hackagent/api/key/key_destroy.py +103 -0
  30. hackagent/api/key/key_list.py +170 -0
  31. hackagent/api/key/key_retrieve.py +162 -0
  32. hackagent/api/organization/__init__.py +1 -0
  33. hackagent/api/organization/organization_create.py +208 -0
  34. hackagent/api/organization/organization_destroy.py +104 -0
  35. hackagent/api/organization/organization_list.py +170 -0
  36. hackagent/api/organization/organization_me_retrieve.py +126 -0
  37. hackagent/api/organization/organization_partial_update.py +222 -0
  38. hackagent/api/organization/organization_retrieve.py +163 -0
  39. hackagent/api/organization/organization_update.py +222 -0
  40. hackagent/api/prompt/__init__.py +1 -0
  41. hackagent/api/prompt/prompt_create.py +171 -0
  42. hackagent/api/prompt/prompt_destroy.py +104 -0
  43. hackagent/api/prompt/prompt_list.py +185 -0
  44. hackagent/api/prompt/prompt_partial_update.py +185 -0
  45. hackagent/api/prompt/prompt_retrieve.py +163 -0
  46. hackagent/api/prompt/prompt_update.py +185 -0
  47. hackagent/api/result/__init__.py +1 -0
  48. hackagent/api/result/result_create.py +175 -0
  49. hackagent/api/result/result_destroy.py +106 -0
  50. hackagent/api/result/result_list.py +249 -0
  51. hackagent/api/result/result_partial_update.py +193 -0
  52. hackagent/api/result/result_retrieve.py +167 -0
  53. hackagent/api/result/result_trace_create.py +177 -0
  54. hackagent/api/result/result_update.py +189 -0
  55. hackagent/api/run/__init__.py +1 -0
  56. hackagent/api/run/run_create.py +187 -0
  57. hackagent/api/run/run_destroy.py +112 -0
  58. hackagent/api/run/run_list.py +291 -0
  59. hackagent/api/run/run_partial_update.py +201 -0
  60. hackagent/api/run/run_result_create.py +177 -0
  61. hackagent/api/run/run_retrieve.py +179 -0
  62. hackagent/api/run/run_run_tests_create.py +187 -0
  63. hackagent/api/run/run_update.py +201 -0
  64. hackagent/api/user/__init__.py +1 -0
  65. hackagent/api/user/user_create.py +212 -0
  66. hackagent/api/user/user_destroy.py +106 -0
  67. hackagent/api/user/user_list.py +174 -0
  68. hackagent/api/user/user_me_retrieve.py +126 -0
  69. hackagent/api/user/user_me_update.py +196 -0
  70. hackagent/api/user/user_partial_update.py +226 -0
  71. hackagent/api/user/user_retrieve.py +167 -0
  72. hackagent/api/user/user_update.py +226 -0
  73. hackagent/attacks/AdvPrefix/__init__.py +41 -0
  74. hackagent/attacks/AdvPrefix/completions.py +416 -0
  75. hackagent/attacks/AdvPrefix/config.py +259 -0
  76. hackagent/attacks/AdvPrefix/evaluation.py +745 -0
  77. hackagent/attacks/AdvPrefix/evaluators.py +564 -0
  78. hackagent/attacks/AdvPrefix/generate.py +711 -0
  79. hackagent/attacks/AdvPrefix/utils.py +307 -0
  80. hackagent/attacks/__init__.py +35 -0
  81. hackagent/attacks/advprefix.py +507 -0
  82. hackagent/attacks/base.py +106 -0
  83. hackagent/attacks/strategies.py +906 -0
  84. hackagent/cli/__init__.py +19 -0
  85. hackagent/cli/commands/__init__.py +20 -0
  86. hackagent/cli/commands/agent.py +100 -0
  87. hackagent/cli/commands/attack.py +417 -0
  88. hackagent/cli/commands/config.py +301 -0
  89. hackagent/cli/commands/results.py +327 -0
  90. hackagent/cli/config.py +249 -0
  91. hackagent/cli/main.py +515 -0
  92. hackagent/cli/tui/__init__.py +31 -0
  93. hackagent/cli/tui/actions_logger.py +200 -0
  94. hackagent/cli/tui/app.py +288 -0
  95. hackagent/cli/tui/base.py +137 -0
  96. hackagent/cli/tui/logger.py +318 -0
  97. hackagent/cli/tui/views/__init__.py +33 -0
  98. hackagent/cli/tui/views/agents.py +488 -0
  99. hackagent/cli/tui/views/attacks.py +624 -0
  100. hackagent/cli/tui/views/config.py +244 -0
  101. hackagent/cli/tui/views/dashboard.py +307 -0
  102. hackagent/cli/tui/views/results.py +1210 -0
  103. hackagent/cli/tui/widgets/__init__.py +24 -0
  104. hackagent/cli/tui/widgets/actions.py +346 -0
  105. hackagent/cli/tui/widgets/logs.py +435 -0
  106. hackagent/cli/utils.py +276 -0
  107. hackagent/client.py +286 -0
  108. hackagent/errors.py +37 -0
  109. hackagent/logger.py +83 -0
  110. hackagent/models/__init__.py +109 -0
  111. hackagent/models/agent.py +223 -0
  112. hackagent/models/agent_request.py +129 -0
  113. hackagent/models/api_token_log.py +184 -0
  114. hackagent/models/attack.py +154 -0
  115. hackagent/models/attack_request.py +82 -0
  116. hackagent/models/checkout_session_request_request.py +76 -0
  117. hackagent/models/checkout_session_response.py +59 -0
  118. hackagent/models/choice.py +81 -0
  119. hackagent/models/choice_message.py +67 -0
  120. hackagent/models/evaluation_status_enum.py +14 -0
  121. hackagent/models/generate_error_response.py +59 -0
  122. hackagent/models/generate_request_request.py +212 -0
  123. hackagent/models/generate_success_response.py +115 -0
  124. hackagent/models/generic_error_response.py +70 -0
  125. hackagent/models/message_request.py +67 -0
  126. hackagent/models/organization.py +102 -0
  127. hackagent/models/organization_minimal.py +68 -0
  128. hackagent/models/organization_request.py +71 -0
  129. hackagent/models/paginated_agent_list.py +123 -0
  130. hackagent/models/paginated_api_token_log_list.py +123 -0
  131. hackagent/models/paginated_attack_list.py +123 -0
  132. hackagent/models/paginated_organization_list.py +123 -0
  133. hackagent/models/paginated_prompt_list.py +123 -0
  134. hackagent/models/paginated_result_list.py +123 -0
  135. hackagent/models/paginated_run_list.py +123 -0
  136. hackagent/models/paginated_user_api_key_list.py +123 -0
  137. hackagent/models/paginated_user_profile_list.py +123 -0
  138. hackagent/models/patched_agent_request.py +128 -0
  139. hackagent/models/patched_attack_request.py +92 -0
  140. hackagent/models/patched_organization_request.py +71 -0
  141. hackagent/models/patched_prompt_request.py +125 -0
  142. hackagent/models/patched_result_request.py +237 -0
  143. hackagent/models/patched_run_request.py +138 -0
  144. hackagent/models/patched_user_profile_request.py +99 -0
  145. hackagent/models/prompt.py +220 -0
  146. hackagent/models/prompt_request.py +126 -0
  147. hackagent/models/result.py +294 -0
  148. hackagent/models/result_list_evaluation_status.py +14 -0
  149. hackagent/models/result_request.py +232 -0
  150. hackagent/models/run.py +233 -0
  151. hackagent/models/run_list_status.py +12 -0
  152. hackagent/models/run_request.py +133 -0
  153. hackagent/models/status_enum.py +12 -0
  154. hackagent/models/step_type_enum.py +14 -0
  155. hackagent/models/trace.py +121 -0
  156. hackagent/models/trace_request.py +94 -0
  157. hackagent/models/usage.py +75 -0
  158. hackagent/models/user_api_key.py +201 -0
  159. hackagent/models/user_api_key_request.py +73 -0
  160. hackagent/models/user_profile.py +135 -0
  161. hackagent/models/user_profile_minimal.py +76 -0
  162. hackagent/models/user_profile_request.py +99 -0
  163. hackagent/router/__init__.py +25 -0
  164. hackagent/router/adapters/__init__.py +20 -0
  165. hackagent/router/adapters/base.py +63 -0
  166. hackagent/router/adapters/google_adk.py +671 -0
  167. hackagent/router/adapters/litellm_adapter.py +524 -0
  168. hackagent/router/adapters/openai_adapter.py +426 -0
  169. hackagent/router/router.py +969 -0
  170. hackagent/router/types.py +54 -0
  171. hackagent/tracking/__init__.py +42 -0
  172. hackagent/tracking/context.py +163 -0
  173. hackagent/tracking/decorators.py +299 -0
  174. hackagent/tracking/tracker.py +441 -0
  175. hackagent/types.py +54 -0
  176. hackagent/utils.py +194 -0
  177. hackagent/vulnerabilities/__init__.py +13 -0
  178. hackagent/vulnerabilities/prompts.py +81 -0
  179. hackagent-0.3.1.dist-info/METADATA +122 -0
  180. hackagent-0.3.1.dist-info/RECORD +183 -0
  181. hackagent-0.3.1.dist-info/WHEEL +4 -0
  182. hackagent-0.3.1.dist-info/entry_points.txt +2 -0
  183. hackagent-0.3.1.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,220 @@
1
+ import datetime
2
+ from collections.abc import Mapping
3
+ from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
4
+ from uuid import UUID
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+ from dateutil.parser import isoparse
9
+
10
+ from ..types import UNSET, Unset
11
+
12
+ if TYPE_CHECKING:
13
+ from ..models.organization_minimal import OrganizationMinimal
14
+ from ..models.user_profile_minimal import UserProfileMinimal
15
+
16
+
17
+ T = TypeVar("T", bound="Prompt")
18
+
19
+
20
+ @_attrs_define
21
+ class Prompt:
22
+ """Serializer for the Prompt model.
23
+
24
+ Attributes:
25
+ id (UUID):
26
+ name (str):
27
+ prompt_text (str):
28
+ organization (UUID):
29
+ organization_detail (OrganizationMinimal):
30
+ owner (Union[None, int]):
31
+ owner_detail (Union['UserProfileMinimal', None]):
32
+ created_at (datetime.datetime):
33
+ updated_at (datetime.datetime):
34
+ category (Union[Unset, str]): Primary category for grouping prompts (e.g., Evasion, Harmful Content).
35
+ tags (Union[Unset, Any]): Optional JSON list of tags for classification (e.g., ["PII", "Malware"])
36
+ evaluation_criteria (Union[Unset, str]): Description of how success/failure should be judged for this specific
37
+ prompt.
38
+ expected_tool_calls (Union[Unset, Any]): JSON list of expected tool calls, e.g., [{"tool_name": "...",
39
+ "tool_input": {...}}]
40
+ expected_output_pattern (Union[Unset, str]): Optional regex pattern to match against the final response.
41
+ reference_output (Union[Unset, str]): Optional ideal/reference final output text.
42
+ """
43
+
44
+ id: UUID
45
+ name: str
46
+ prompt_text: str
47
+ organization: UUID
48
+ organization_detail: "OrganizationMinimal"
49
+ owner: Union[None, int]
50
+ owner_detail: Union["UserProfileMinimal", None]
51
+ created_at: datetime.datetime
52
+ updated_at: datetime.datetime
53
+ category: Union[Unset, str] = UNSET
54
+ tags: Union[Unset, Any] = UNSET
55
+ evaluation_criteria: Union[Unset, str] = UNSET
56
+ expected_tool_calls: Union[Unset, Any] = UNSET
57
+ expected_output_pattern: Union[Unset, str] = UNSET
58
+ reference_output: Union[Unset, str] = UNSET
59
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
60
+
61
+ def to_dict(self) -> dict[str, Any]:
62
+ from ..models.user_profile_minimal import UserProfileMinimal
63
+
64
+ id = str(self.id)
65
+
66
+ name = self.name
67
+
68
+ prompt_text = self.prompt_text
69
+
70
+ organization = str(self.organization)
71
+
72
+ organization_detail = self.organization_detail.to_dict()
73
+
74
+ owner: Union[None, int]
75
+ owner = self.owner
76
+
77
+ owner_detail: Union[None, dict[str, Any]]
78
+ if isinstance(self.owner_detail, UserProfileMinimal):
79
+ owner_detail = self.owner_detail.to_dict()
80
+ else:
81
+ owner_detail = self.owner_detail
82
+
83
+ created_at = self.created_at.isoformat()
84
+
85
+ updated_at = self.updated_at.isoformat()
86
+
87
+ category = self.category
88
+
89
+ tags = self.tags
90
+
91
+ evaluation_criteria = self.evaluation_criteria
92
+
93
+ expected_tool_calls = self.expected_tool_calls
94
+
95
+ expected_output_pattern = self.expected_output_pattern
96
+
97
+ reference_output = self.reference_output
98
+
99
+ field_dict: dict[str, Any] = {}
100
+ field_dict.update(self.additional_properties)
101
+ field_dict.update(
102
+ {
103
+ "id": id,
104
+ "name": name,
105
+ "prompt_text": prompt_text,
106
+ "organization": organization,
107
+ "organization_detail": organization_detail,
108
+ "owner": owner,
109
+ "owner_detail": owner_detail,
110
+ "created_at": created_at,
111
+ "updated_at": updated_at,
112
+ }
113
+ )
114
+ if category is not UNSET:
115
+ field_dict["category"] = category
116
+ if tags is not UNSET:
117
+ field_dict["tags"] = tags
118
+ if evaluation_criteria is not UNSET:
119
+ field_dict["evaluation_criteria"] = evaluation_criteria
120
+ if expected_tool_calls is not UNSET:
121
+ field_dict["expected_tool_calls"] = expected_tool_calls
122
+ if expected_output_pattern is not UNSET:
123
+ field_dict["expected_output_pattern"] = expected_output_pattern
124
+ if reference_output is not UNSET:
125
+ field_dict["reference_output"] = reference_output
126
+
127
+ return field_dict
128
+
129
+ @classmethod
130
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
131
+ from ..models.organization_minimal import OrganizationMinimal
132
+ from ..models.user_profile_minimal import UserProfileMinimal
133
+
134
+ d = dict(src_dict)
135
+ id = UUID(d.pop("id"))
136
+
137
+ name = d.pop("name")
138
+
139
+ prompt_text = d.pop("prompt_text")
140
+
141
+ organization = UUID(d.pop("organization"))
142
+
143
+ organization_detail = OrganizationMinimal.from_dict(
144
+ d.pop("organization_detail")
145
+ )
146
+
147
+ def _parse_owner(data: object) -> Union[None, int]:
148
+ if data is None:
149
+ return data
150
+ return cast(Union[None, int], data)
151
+
152
+ owner = _parse_owner(d.pop("owner"))
153
+
154
+ def _parse_owner_detail(data: object) -> Union["UserProfileMinimal", None]:
155
+ if data is None:
156
+ return data
157
+ try:
158
+ if not isinstance(data, dict):
159
+ raise TypeError()
160
+ owner_detail_type_1 = UserProfileMinimal.from_dict(data)
161
+
162
+ return owner_detail_type_1
163
+ except: # noqa: E722
164
+ pass
165
+ return cast(Union["UserProfileMinimal", None], data)
166
+
167
+ owner_detail = _parse_owner_detail(d.pop("owner_detail"))
168
+
169
+ created_at = isoparse(d.pop("created_at"))
170
+
171
+ updated_at = isoparse(d.pop("updated_at"))
172
+
173
+ category = d.pop("category", UNSET)
174
+
175
+ tags = d.pop("tags", UNSET)
176
+
177
+ evaluation_criteria = d.pop("evaluation_criteria", UNSET)
178
+
179
+ expected_tool_calls = d.pop("expected_tool_calls", UNSET)
180
+
181
+ expected_output_pattern = d.pop("expected_output_pattern", UNSET)
182
+
183
+ reference_output = d.pop("reference_output", UNSET)
184
+
185
+ prompt = cls(
186
+ id=id,
187
+ name=name,
188
+ prompt_text=prompt_text,
189
+ organization=organization,
190
+ organization_detail=organization_detail,
191
+ owner=owner,
192
+ owner_detail=owner_detail,
193
+ created_at=created_at,
194
+ updated_at=updated_at,
195
+ category=category,
196
+ tags=tags,
197
+ evaluation_criteria=evaluation_criteria,
198
+ expected_tool_calls=expected_tool_calls,
199
+ expected_output_pattern=expected_output_pattern,
200
+ reference_output=reference_output,
201
+ )
202
+
203
+ prompt.additional_properties = d
204
+ return prompt
205
+
206
+ @property
207
+ def additional_keys(self) -> list[str]:
208
+ return list(self.additional_properties.keys())
209
+
210
+ def __getitem__(self, key: str) -> Any:
211
+ return self.additional_properties[key]
212
+
213
+ def __setitem__(self, key: str, value: Any) -> None:
214
+ self.additional_properties[key] = value
215
+
216
+ def __delitem__(self, key: str) -> None:
217
+ del self.additional_properties[key]
218
+
219
+ def __contains__(self, key: str) -> bool:
220
+ return key in self.additional_properties
@@ -0,0 +1,126 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any, TypeVar, Union
3
+
4
+ from attrs import define as _attrs_define
5
+ from attrs import field as _attrs_field
6
+
7
+ from ..types import UNSET, Unset
8
+
9
+ T = TypeVar("T", bound="PromptRequest")
10
+
11
+
12
+ @_attrs_define
13
+ class PromptRequest:
14
+ """Serializer for the Prompt model.
15
+
16
+ Attributes:
17
+ name (str):
18
+ prompt_text (str):
19
+ category (Union[Unset, str]): Primary category for grouping prompts (e.g., Evasion, Harmful Content).
20
+ tags (Union[Unset, Any]): Optional JSON list of tags for classification (e.g., ["PII", "Malware"])
21
+ evaluation_criteria (Union[Unset, str]): Description of how success/failure should be judged for this specific
22
+ prompt.
23
+ expected_tool_calls (Union[Unset, Any]): JSON list of expected tool calls, e.g., [{"tool_name": "...",
24
+ "tool_input": {...}}]
25
+ expected_output_pattern (Union[Unset, str]): Optional regex pattern to match against the final response.
26
+ reference_output (Union[Unset, str]): Optional ideal/reference final output text.
27
+ """
28
+
29
+ name: str
30
+ prompt_text: str
31
+ category: Union[Unset, str] = UNSET
32
+ tags: Union[Unset, Any] = UNSET
33
+ evaluation_criteria: Union[Unset, str] = UNSET
34
+ expected_tool_calls: Union[Unset, Any] = UNSET
35
+ expected_output_pattern: Union[Unset, str] = UNSET
36
+ reference_output: Union[Unset, str] = UNSET
37
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
38
+
39
+ def to_dict(self) -> dict[str, Any]:
40
+ name = self.name
41
+
42
+ prompt_text = self.prompt_text
43
+
44
+ category = self.category
45
+
46
+ tags = self.tags
47
+
48
+ evaluation_criteria = self.evaluation_criteria
49
+
50
+ expected_tool_calls = self.expected_tool_calls
51
+
52
+ expected_output_pattern = self.expected_output_pattern
53
+
54
+ reference_output = self.reference_output
55
+
56
+ field_dict: dict[str, Any] = {}
57
+ field_dict.update(self.additional_properties)
58
+ field_dict.update(
59
+ {
60
+ "name": name,
61
+ "prompt_text": prompt_text,
62
+ }
63
+ )
64
+ if category is not UNSET:
65
+ field_dict["category"] = category
66
+ if tags is not UNSET:
67
+ field_dict["tags"] = tags
68
+ if evaluation_criteria is not UNSET:
69
+ field_dict["evaluation_criteria"] = evaluation_criteria
70
+ if expected_tool_calls is not UNSET:
71
+ field_dict["expected_tool_calls"] = expected_tool_calls
72
+ if expected_output_pattern is not UNSET:
73
+ field_dict["expected_output_pattern"] = expected_output_pattern
74
+ if reference_output is not UNSET:
75
+ field_dict["reference_output"] = reference_output
76
+
77
+ return field_dict
78
+
79
+ @classmethod
80
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
81
+ d = dict(src_dict)
82
+ name = d.pop("name")
83
+
84
+ prompt_text = d.pop("prompt_text")
85
+
86
+ category = d.pop("category", UNSET)
87
+
88
+ tags = d.pop("tags", UNSET)
89
+
90
+ evaluation_criteria = d.pop("evaluation_criteria", UNSET)
91
+
92
+ expected_tool_calls = d.pop("expected_tool_calls", UNSET)
93
+
94
+ expected_output_pattern = d.pop("expected_output_pattern", UNSET)
95
+
96
+ reference_output = d.pop("reference_output", UNSET)
97
+
98
+ prompt_request = cls(
99
+ name=name,
100
+ prompt_text=prompt_text,
101
+ category=category,
102
+ tags=tags,
103
+ evaluation_criteria=evaluation_criteria,
104
+ expected_tool_calls=expected_tool_calls,
105
+ expected_output_pattern=expected_output_pattern,
106
+ reference_output=reference_output,
107
+ )
108
+
109
+ prompt_request.additional_properties = d
110
+ return prompt_request
111
+
112
+ @property
113
+ def additional_keys(self) -> list[str]:
114
+ return list(self.additional_properties.keys())
115
+
116
+ def __getitem__(self, key: str) -> Any:
117
+ return self.additional_properties[key]
118
+
119
+ def __setitem__(self, key: str, value: Any) -> None:
120
+ self.additional_properties[key] = value
121
+
122
+ def __delitem__(self, key: str) -> None:
123
+ del self.additional_properties[key]
124
+
125
+ def __contains__(self, key: str) -> bool:
126
+ return key in self.additional_properties
@@ -0,0 +1,294 @@
1
+ import datetime
2
+ from collections.abc import Mapping
3
+ from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
4
+ from uuid import UUID
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+ from dateutil.parser import isoparse
9
+
10
+ from ..models.evaluation_status_enum import EvaluationStatusEnum
11
+ from ..types import UNSET, Unset
12
+
13
+ if TYPE_CHECKING:
14
+ from ..models.trace import Trace
15
+
16
+
17
+ T = TypeVar("T", bound="Result")
18
+
19
+
20
+ @_attrs_define
21
+ class Result:
22
+ """Serializer for the Result model, often nested in RunSerializer.
23
+
24
+ Attributes:
25
+ id (UUID):
26
+ run (UUID):
27
+ run_id (UUID):
28
+ prompt_name (Union[None, str]):
29
+ timestamp (datetime.datetime):
30
+ traces (list['Trace']):
31
+ prompt (Union[None, UUID, Unset]):
32
+ request_payload (Union[Unset, Any]): Payload sent to agent or relevant data for client-submitted results.
33
+ response_status_code (Union[None, Unset, int]):
34
+ response_headers (Union[Unset, Any]):
35
+ response_body (Union[None, Unset, str]):
36
+ latency_ms (Union[None, Unset, int]):
37
+ detected_tool_calls (Union[Unset, Any]):
38
+ evaluation_status (Union[Unset, EvaluationStatusEnum]): * `NOT_EVALUATED` - Not Evaluated
39
+ * `SUCCESSFUL_JAILBREAK` - Successful Jailbreak
40
+ * `FAILED_JAILBREAK` - Failed Jailbreak (Mitigated/Refused)
41
+ * `ERROR_AGENT_RESPONSE` - Error in Agent Response
42
+ * `ERROR_TEST_FRAMEWORK` - Error in Test Framework
43
+ * `PASSED_CRITERIA` - Passed Criteria (Not Jailbreak)
44
+ * `FAILED_CRITERIA` - Failed Criteria (Not Jailbreak)
45
+ evaluation_notes (Union[Unset, str]):
46
+ evaluation_metrics (Union[Unset, Any]):
47
+ agent_specific_data (Union[Unset, Any]):
48
+ """
49
+
50
+ id: UUID
51
+ run: UUID
52
+ run_id: UUID
53
+ prompt_name: Union[None, str]
54
+ timestamp: datetime.datetime
55
+ traces: list["Trace"]
56
+ prompt: Union[None, UUID, Unset] = UNSET
57
+ request_payload: Union[Unset, Any] = UNSET
58
+ response_status_code: Union[None, Unset, int] = UNSET
59
+ response_headers: Union[Unset, Any] = UNSET
60
+ response_body: Union[None, Unset, str] = UNSET
61
+ latency_ms: Union[None, Unset, int] = UNSET
62
+ detected_tool_calls: Union[Unset, Any] = UNSET
63
+ evaluation_status: Union[Unset, EvaluationStatusEnum] = UNSET
64
+ evaluation_notes: Union[Unset, str] = UNSET
65
+ evaluation_metrics: Union[Unset, Any] = UNSET
66
+ agent_specific_data: Union[Unset, Any] = UNSET
67
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
68
+
69
+ def to_dict(self) -> dict[str, Any]:
70
+ id = str(self.id)
71
+
72
+ run = str(self.run)
73
+
74
+ run_id = str(self.run_id)
75
+
76
+ prompt_name: Union[None, str]
77
+ prompt_name = self.prompt_name
78
+
79
+ timestamp = self.timestamp.isoformat()
80
+
81
+ traces = []
82
+ for traces_item_data in self.traces:
83
+ traces_item = traces_item_data.to_dict()
84
+ traces.append(traces_item)
85
+
86
+ prompt: Union[None, Unset, str]
87
+ if isinstance(self.prompt, Unset):
88
+ prompt = UNSET
89
+ elif isinstance(self.prompt, UUID):
90
+ prompt = str(self.prompt)
91
+ else:
92
+ prompt = self.prompt
93
+
94
+ request_payload = self.request_payload
95
+
96
+ response_status_code: Union[None, Unset, int]
97
+ if isinstance(self.response_status_code, Unset):
98
+ response_status_code = UNSET
99
+ else:
100
+ response_status_code = self.response_status_code
101
+
102
+ response_headers = self.response_headers
103
+
104
+ response_body: Union[None, Unset, str]
105
+ if isinstance(self.response_body, Unset):
106
+ response_body = UNSET
107
+ else:
108
+ response_body = self.response_body
109
+
110
+ latency_ms: Union[None, Unset, int]
111
+ if isinstance(self.latency_ms, Unset):
112
+ latency_ms = UNSET
113
+ else:
114
+ latency_ms = self.latency_ms
115
+
116
+ detected_tool_calls = self.detected_tool_calls
117
+
118
+ evaluation_status: Union[Unset, str] = UNSET
119
+ if not isinstance(self.evaluation_status, Unset):
120
+ evaluation_status = self.evaluation_status.value
121
+
122
+ evaluation_notes = self.evaluation_notes
123
+
124
+ evaluation_metrics = self.evaluation_metrics
125
+
126
+ agent_specific_data = self.agent_specific_data
127
+
128
+ field_dict: dict[str, Any] = {}
129
+ field_dict.update(self.additional_properties)
130
+ field_dict.update(
131
+ {
132
+ "id": id,
133
+ "run": run,
134
+ "run_id": run_id,
135
+ "prompt_name": prompt_name,
136
+ "timestamp": timestamp,
137
+ "traces": traces,
138
+ }
139
+ )
140
+ if prompt is not UNSET:
141
+ field_dict["prompt"] = prompt
142
+ if request_payload is not UNSET:
143
+ field_dict["request_payload"] = request_payload
144
+ if response_status_code is not UNSET:
145
+ field_dict["response_status_code"] = response_status_code
146
+ if response_headers is not UNSET:
147
+ field_dict["response_headers"] = response_headers
148
+ if response_body is not UNSET:
149
+ field_dict["response_body"] = response_body
150
+ if latency_ms is not UNSET:
151
+ field_dict["latency_ms"] = latency_ms
152
+ if detected_tool_calls is not UNSET:
153
+ field_dict["detected_tool_calls"] = detected_tool_calls
154
+ if evaluation_status is not UNSET:
155
+ field_dict["evaluation_status"] = evaluation_status
156
+ if evaluation_notes is not UNSET:
157
+ field_dict["evaluation_notes"] = evaluation_notes
158
+ if evaluation_metrics is not UNSET:
159
+ field_dict["evaluation_metrics"] = evaluation_metrics
160
+ if agent_specific_data is not UNSET:
161
+ field_dict["agent_specific_data"] = agent_specific_data
162
+
163
+ return field_dict
164
+
165
+ @classmethod
166
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
167
+ from ..models.trace import Trace
168
+
169
+ d = dict(src_dict)
170
+ id = UUID(d.pop("id"))
171
+
172
+ run = UUID(d.pop("run"))
173
+
174
+ run_id = UUID(d.pop("run_id"))
175
+
176
+ def _parse_prompt_name(data: object) -> Union[None, str]:
177
+ if data is None:
178
+ return data
179
+ return cast(Union[None, str], data)
180
+
181
+ prompt_name = _parse_prompt_name(d.pop("prompt_name"))
182
+
183
+ timestamp = isoparse(d.pop("timestamp"))
184
+
185
+ traces = []
186
+ _traces = d.pop("traces")
187
+ for traces_item_data in _traces:
188
+ traces_item = Trace.from_dict(traces_item_data)
189
+
190
+ traces.append(traces_item)
191
+
192
+ def _parse_prompt(data: object) -> Union[None, UUID, Unset]:
193
+ if data is None:
194
+ return data
195
+ if isinstance(data, Unset):
196
+ return data
197
+ try:
198
+ if not isinstance(data, str):
199
+ raise TypeError()
200
+ prompt_type_0 = UUID(data)
201
+
202
+ return prompt_type_0
203
+ except: # noqa: E722
204
+ pass
205
+ return cast(Union[None, UUID, Unset], data)
206
+
207
+ prompt = _parse_prompt(d.pop("prompt", UNSET))
208
+
209
+ request_payload = d.pop("request_payload", UNSET)
210
+
211
+ def _parse_response_status_code(data: object) -> Union[None, Unset, int]:
212
+ if data is None:
213
+ return data
214
+ if isinstance(data, Unset):
215
+ return data
216
+ return cast(Union[None, Unset, int], data)
217
+
218
+ response_status_code = _parse_response_status_code(
219
+ d.pop("response_status_code", UNSET)
220
+ )
221
+
222
+ response_headers = d.pop("response_headers", UNSET)
223
+
224
+ def _parse_response_body(data: object) -> Union[None, Unset, str]:
225
+ if data is None:
226
+ return data
227
+ if isinstance(data, Unset):
228
+ return data
229
+ return cast(Union[None, Unset, str], data)
230
+
231
+ response_body = _parse_response_body(d.pop("response_body", UNSET))
232
+
233
+ def _parse_latency_ms(data: object) -> Union[None, Unset, int]:
234
+ if data is None:
235
+ return data
236
+ if isinstance(data, Unset):
237
+ return data
238
+ return cast(Union[None, Unset, int], data)
239
+
240
+ latency_ms = _parse_latency_ms(d.pop("latency_ms", UNSET))
241
+
242
+ detected_tool_calls = d.pop("detected_tool_calls", UNSET)
243
+
244
+ _evaluation_status = d.pop("evaluation_status", UNSET)
245
+ evaluation_status: Union[Unset, EvaluationStatusEnum]
246
+ if isinstance(_evaluation_status, Unset):
247
+ evaluation_status = UNSET
248
+ else:
249
+ evaluation_status = EvaluationStatusEnum(_evaluation_status)
250
+
251
+ evaluation_notes = d.pop("evaluation_notes", UNSET)
252
+
253
+ evaluation_metrics = d.pop("evaluation_metrics", UNSET)
254
+
255
+ agent_specific_data = d.pop("agent_specific_data", UNSET)
256
+
257
+ result = cls(
258
+ id=id,
259
+ run=run,
260
+ run_id=run_id,
261
+ prompt_name=prompt_name,
262
+ timestamp=timestamp,
263
+ traces=traces,
264
+ prompt=prompt,
265
+ request_payload=request_payload,
266
+ response_status_code=response_status_code,
267
+ response_headers=response_headers,
268
+ response_body=response_body,
269
+ latency_ms=latency_ms,
270
+ detected_tool_calls=detected_tool_calls,
271
+ evaluation_status=evaluation_status,
272
+ evaluation_notes=evaluation_notes,
273
+ evaluation_metrics=evaluation_metrics,
274
+ agent_specific_data=agent_specific_data,
275
+ )
276
+
277
+ result.additional_properties = d
278
+ return result
279
+
280
+ @property
281
+ def additional_keys(self) -> list[str]:
282
+ return list(self.additional_properties.keys())
283
+
284
+ def __getitem__(self, key: str) -> Any:
285
+ return self.additional_properties[key]
286
+
287
+ def __setitem__(self, key: str, value: Any) -> None:
288
+ self.additional_properties[key] = value
289
+
290
+ def __delitem__(self, key: str) -> None:
291
+ del self.additional_properties[key]
292
+
293
+ def __contains__(self, key: str) -> bool:
294
+ return key in self.additional_properties
@@ -0,0 +1,14 @@
1
+ from enum import Enum
2
+
3
+
4
+ class ResultListEvaluationStatus(str, Enum):
5
+ ERROR_AGENT_RESPONSE = "ERROR_AGENT_RESPONSE"
6
+ ERROR_TEST_FRAMEWORK = "ERROR_TEST_FRAMEWORK"
7
+ FAILED_CRITERIA = "FAILED_CRITERIA"
8
+ FAILED_JAILBREAK = "FAILED_JAILBREAK"
9
+ NOT_EVALUATED = "NOT_EVALUATED"
10
+ PASSED_CRITERIA = "PASSED_CRITERIA"
11
+ SUCCESSFUL_JAILBREAK = "SUCCESSFUL_JAILBREAK"
12
+
13
+ def __str__(self) -> str:
14
+ return str(self.value)