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.
Files changed (37) hide show
  1. {aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/METADATA +24 -26
  2. {aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/RECORD +37 -36
  3. {aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/WHEEL +1 -1
  4. moonshot/integrations/cli/benchmark/cookbook.py +8 -11
  5. moonshot/integrations/cli/benchmark/recipe.py +1 -5
  6. moonshot/integrations/cli/cli_errors.py +3 -0
  7. moonshot/integrations/cli/common/connectors.py +22 -10
  8. moonshot/integrations/web_api/app.py +1 -1
  9. moonshot/integrations/web_api/schemas/endpoint_create_dto.py +1 -0
  10. moonshot/integrations/web_api/services/endpoint_service.py +1 -0
  11. moonshot/src/api/api_bookmark.py +16 -5
  12. moonshot/src/api/api_connector.py +3 -3
  13. moonshot/src/api/api_connector_endpoint.py +6 -3
  14. moonshot/src/api/api_context_strategy.py +2 -2
  15. moonshot/src/api/api_cookbook.py +6 -6
  16. moonshot/src/api/api_dataset.py +5 -5
  17. moonshot/src/api/api_environment_variables.py +3 -0
  18. moonshot/src/api/api_metrics.py +1 -1
  19. moonshot/src/api/api_prompt_template.py +9 -0
  20. moonshot/src/api/api_recipe.py +3 -3
  21. moonshot/src/api/api_red_teaming.py +4 -8
  22. moonshot/src/api/api_result.py +10 -6
  23. moonshot/src/api/api_run.py +3 -3
  24. moonshot/src/api/api_runner.py +7 -6
  25. moonshot/src/api/api_session.py +11 -7
  26. moonshot/src/bookmark/bookmark.py +12 -5
  27. moonshot/src/connectors/connector.py +127 -62
  28. moonshot/src/connectors/connector_prompt_arguments.py +15 -5
  29. moonshot/src/connectors/connector_response.py +15 -0
  30. moonshot/src/connectors_endpoints/connector_endpoint.py +32 -20
  31. moonshot/src/connectors_endpoints/connector_endpoint_arguments.py +4 -1
  32. moonshot/src/messages_constants.py +85 -3
  33. moonshot/src/redteaming/attack/attack_module.py +34 -7
  34. moonshot/src/runs/run_arguments.py +43 -20
  35. {aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/licenses/AUTHORS.md +0 -0
  36. {aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/licenses/LICENSE.md +0 -0
  37. {aiverify_moonshot-0.4.10.dist-info → aiverify_moonshot-0.5.0.dist-info}/licenses/NOTICES.md +0 -0
@@ -3,16 +3,32 @@ from __future__ import annotations
3
3
  import asyncio
4
4
  import time
5
5
  from abc import abstractmethod
6
- from asyncio import sleep
7
- from functools import wraps
6
+ from functools import partial, wraps
8
7
  from pathlib import Path
9
8
  from typing import Callable
10
9
 
10
+ from tenacity import RetryCallState, retry, stop_after_attempt, wait_random_exponential
11
+
11
12
  from moonshot.src.configs.env_variables import EnvVariables
12
13
  from moonshot.src.connectors.connector_prompt_arguments import ConnectorPromptArguments
14
+ from moonshot.src.connectors.connector_response import ConnectorResponse
13
15
  from moonshot.src.connectors_endpoints.connector_endpoint_arguments import (
14
16
  ConnectorEndpointArguments,
15
17
  )
18
+ from moonshot.src.messages_constants import (
19
+ CONNECTOR_CREATE_CONNECTOR_ENDPOINT_ARGUMENTS_VALIDATION_ERROR,
20
+ CONNECTOR_CREATE_ERROR,
21
+ CONNECTOR_GET_AVAILABLE_ITEMS_ERROR,
22
+ CONNECTOR_GET_PREDICTION_ARGUMENTS_CONNECTOR_VALIDATION_ERROR,
23
+ CONNECTOR_GET_PREDICTION_ARGUMENTS_GENERATED_PROMPT_VALIDATION_ERROR,
24
+ CONNECTOR_GET_PREDICTION_ERROR,
25
+ CONNECTOR_GET_PREDICTION_INFO,
26
+ CONNECTOR_GET_PREDICTION_TIME_TAKEN_INFO,
27
+ CONNECTOR_LOAD_CONNECTOR_ENDPOINT_ARGUMENTS_VALIDATION_ERROR,
28
+ CONNECTOR_LOAD_CONNECTOR_INSTANCE_RUNTIME_ERROR,
29
+ CONNECTOR_PERFORM_RETRY_CALLBACK_ERROR,
30
+ CONNECTOR_SET_SYSTEM_PROMPT_VALIDATION_ERROR,
31
+ )
16
32
  from moonshot.src.storage.storage import Storage
17
33
  from moonshot.src.utils.import_modules import get_instance
18
34
  from moonshot.src.utils.log import configure_logger
@@ -21,43 +37,56 @@ from moonshot.src.utils.log import configure_logger
21
37
  logger = configure_logger(__name__)
22
38
 
23
39
 
40
+ def perform_retry_callback(connector_id: str, retry_state: RetryCallState) -> None:
41
+ """
42
+ Callback function to log retry attempts with detailed information.
43
+
44
+ This function is called by the tenacity library before each retry attempt.
45
+ It logs the retry attempt number, the sleep time before the next attempt,
46
+ the error message that caused the retry, and the connector ID.
47
+
48
+ Args:
49
+ connector_id (str): The ID of the connector.
50
+ retry_state (RetryCallState): The state of the retry call, which includes
51
+ information about the current attempt, the exception raised, and the next action.
52
+ """
53
+ sleep_time = retry_state.idle_for if retry_state else 0
54
+ exception = (
55
+ retry_state.outcome.exception() if retry_state.outcome else "Unknown exception"
56
+ )
57
+ logger.error(
58
+ CONNECTOR_PERFORM_RETRY_CALLBACK_ERROR.format(
59
+ connector_id=connector_id,
60
+ attempt_no=retry_state.attempt_number,
61
+ sleep=f"{sleep_time:.2f}",
62
+ message=str(exception),
63
+ )
64
+ )
65
+
66
+
24
67
  def perform_retry(func):
25
68
  """
26
- A decorator to perform retries on a function.
69
+ A decorator to perform retries on a function using tenacity.
27
70
 
28
- This decorator wraps a function to enable retrying the function call
29
- if it fails. The number of retries and the delay between retries
30
- are determined by the `retries_times` and `allow_retries`
31
- attributes of the class instance.
71
+ This decorator wraps an asynchronous function to enable retrying the function call
72
+ if it fails. The number of attempts and the delay between attempts
73
+ are determined by the `max_attempts` attribute of the class instance.
32
74
 
33
- Parameters:
34
- - func (Callable): The function to be wrapped and retried.
75
+ Args:
76
+ func (Callable): The asynchronous function to be wrapped and retried.
35
77
 
36
78
  Returns:
37
- - Callable: A wrapper function that includes retry logic.
79
+ Callable: A wrapper function that includes retry logic.
38
80
  """
39
81
 
40
82
  async def wrapper(self, *args, **kwargs):
41
- if self.allow_retries:
42
- retry_count = 0
43
- base_delay = 1
44
- while retry_count <= self.retries_times:
45
- # Perform the request
46
- try:
47
- return await func(self, *args, **kwargs)
48
- except Exception as exc:
49
- logger.warning(f"Operation failed. {str(exc)} - Retrying...")
50
-
51
- # Perform retry
52
- retry_count += 1
53
- if retry_count <= self.retries_times:
54
- delay = base_delay * (2**retry_count)
55
- logger.warning(
56
- f"Attempt {retry_count}, Retrying in {delay} seconds..."
57
- )
58
- await sleep(delay)
59
- # Raise an exception
60
- raise ConnectionError("Failed to get response.")
83
+ retry_decorator = retry(
84
+ wait=wait_random_exponential(min=1, max=60),
85
+ stop=stop_after_attempt(self.max_attempts),
86
+ after=partial(perform_retry_callback, self.id),
87
+ reraise=True,
88
+ )
89
+ return await retry_decorator(func)(self, *args, **kwargs)
61
90
 
62
91
  return wrapper
63
92
 
@@ -70,6 +99,7 @@ class Connector:
70
99
  self.token = ep_args.token
71
100
  self.max_concurrency = ep_args.max_concurrency
72
101
  self.max_calls_per_second = ep_args.max_calls_per_second
102
+ self.model = ep_args.model
73
103
  self.params = ep_args.params
74
104
 
75
105
  # Rate limiting
@@ -79,21 +109,19 @@ class Connector:
79
109
  self.updated_at = time.time()
80
110
  self.semaphore = asyncio.Semaphore(ep_args.max_concurrency)
81
111
 
82
- # Set Prompts if they exists
112
+ # Set Prompts if they exist
83
113
  self.pre_prompt = ep_args.params.get("pre_prompt", "")
84
114
  self.post_prompt = ep_args.params.get("post_prompt", "")
85
115
  self.system_prompt = ep_args.params.get("system_prompt", "")
86
116
 
87
117
  # Connection timeout
88
118
  self.timeout = ep_args.params.get("timeout", 600)
89
- self.allow_retries = ep_args.params.get("allow_retries", True)
90
- self.retries_times = ep_args.params.get("num_of_retries", 3)
119
+ self.max_attempts = ep_args.params.get("max_attempts", 3)
91
120
 
92
121
  # Optional params
93
122
  excluded_keys = {
94
- "allow_retries",
95
123
  "timeout",
96
- "num_of_retries",
124
+ "max_attempts",
97
125
  "pre_prompt",
98
126
  "post_prompt",
99
127
  "system_prompt",
@@ -113,10 +141,6 @@ class Connector:
113
141
 
114
142
  The method updates the `updated_at` attribute to the current time after tokens are added, ensuring that
115
143
  the next token addition will be calculated based on the correct elapsed time.
116
-
117
- Usage:
118
- # Assume `self` is an instance of a class with `rate_limiter`, `tokens`, and `updated_at` attributes.
119
- await self.add_tokens()
120
144
  """
121
145
  now = time.time()
122
146
  elapsed = now - self.updated_at
@@ -143,11 +167,6 @@ class Connector:
143
167
 
144
168
  Returns:
145
169
  Callable: The decorated function wrapped with rate limiting logic.
146
-
147
- Usage:
148
- @rate_limited
149
- async def some_async_function(*args, **kwargs):
150
- # Function implementation
151
170
  """
152
171
 
153
172
  @wraps(func)
@@ -168,9 +187,9 @@ class Connector:
168
187
  return wrapper
169
188
 
170
189
  @abstractmethod
171
- async def get_response(self, prompt: str) -> str:
190
+ async def get_response(self, prompt: str) -> ConnectorResponse:
172
191
  """
173
- Abstract method to be implemented by subclasses to get a response from the connector.
192
+ Abstract method to be implemented by subclasses to obtain a response from the connector.
174
193
 
175
194
  This method should asynchronously send a prompt to the connector's API and return the response.
176
195
 
@@ -178,14 +197,15 @@ class Connector:
178
197
  prompt (str): The input prompt to be sent to the connector.
179
198
 
180
199
  Returns:
181
- str: The response received from the connector.
200
+ ConnectorResponse: An instance containing the response received from the connector and any
201
+ additional metadata.
182
202
  """
183
203
  pass
184
204
 
185
205
  @classmethod
186
206
  def load(cls, ep_args: ConnectorEndpointArguments) -> Connector:
187
207
  """
188
- This method dynamically loads a connector instance based on the provided endpoint arguments.
208
+ Dynamically loads a connector instance based on the provided endpoint arguments.
189
209
 
190
210
  The connector type specified in the `ep_args` is used to dynamically load the corresponding
191
211
  connector class. The connector is then instantiated with the provided endpoint arguments. If the
@@ -201,17 +221,24 @@ class Connector:
201
221
  Raises:
202
222
  RuntimeError: If the specified connector type does not match any available connector classes.
203
223
  """
224
+ if ep_args is None or not isinstance(ep_args, ConnectorEndpointArguments):
225
+ raise ValueError(
226
+ CONNECTOR_LOAD_CONNECTOR_ENDPOINT_ARGUMENTS_VALIDATION_ERROR
227
+ )
228
+
204
229
  connector_instance = get_instance(
205
230
  ep_args.connector_type,
206
231
  Storage.get_filepath(
207
232
  EnvVariables.CONNECTORS.name, ep_args.connector_type, "py"
208
233
  ),
209
234
  )
210
- if connector_instance:
235
+ if connector_instance and isinstance(connector_instance, Callable):
211
236
  return connector_instance(ep_args)
212
237
  else:
213
238
  raise RuntimeError(
214
- f"Unable to get defined connector instance - {ep_args.connector_type}"
239
+ CONNECTOR_LOAD_CONNECTOR_INSTANCE_RUNTIME_ERROR.format(
240
+ message=ep_args.connector_type
241
+ )
215
242
  )
216
243
 
217
244
  @staticmethod
@@ -221,7 +248,7 @@ class Connector:
221
248
 
222
249
  This method takes a ConnectorEndpointArguments object, which contains the necessary information
223
250
  to initialize and return a Connector object. The Connector object is created by calling the
224
- `load_connector` method, which dynamically loads and initializes the connector based on the
251
+ `load` method, which dynamically loads and initializes the connector based on the
225
252
  endpoint arguments provided.
226
253
 
227
254
  Args:
@@ -229,12 +256,20 @@ class Connector:
229
256
 
230
257
  Returns:
231
258
  Connector: An initialized Connector object based on the provided endpoint arguments.
259
+
260
+ Raises:
261
+ ValueError: If the provided endpoint arguments are invalid.
262
+ Exception: If there is an error during the creation of the connector.
232
263
  """
233
264
  try:
265
+ if ep_args is None or not isinstance(ep_args, ConnectorEndpointArguments):
266
+ raise ValueError(
267
+ CONNECTOR_CREATE_CONNECTOR_ENDPOINT_ARGUMENTS_VALIDATION_ERROR
268
+ )
234
269
  return Connector.load(ep_args)
235
270
 
236
271
  except Exception as e:
237
- logger.error(f"Failed to create connector: {str(e)}")
272
+ logger.error(CONNECTOR_CREATE_ERROR.format(message=str(e)))
238
273
  raise e
239
274
 
240
275
  @staticmethod
@@ -243,7 +278,7 @@ class Connector:
243
278
  Fetches a list of all available connector types.
244
279
 
245
280
  This method employs the `get_connectors` method to locate all Python files in the directory
246
- defined by the `EnvironmentVars.CONNECTORS` environment variable. It subsequently excludes any files that are
281
+ defined by the `EnvVariables.CONNECTORS` environment variable. It subsequently excludes any files that are
247
282
  not intended to be exposed as connectors (those containing "__" in their names). The method yields a list of the
248
283
  names of these connector types.
249
284
 
@@ -261,7 +296,7 @@ class Connector:
261
296
  ]
262
297
 
263
298
  except Exception as e:
264
- logger.error(f"Failed to get available connectors: {str(e)}")
299
+ logger.error(CONNECTOR_GET_AVAILABLE_ITEMS_ERROR.format(message=str(e)))
265
300
  raise e
266
301
 
267
302
  @staticmethod
@@ -277,7 +312,7 @@ class Connector:
277
312
  object, which is used to generate the prediction. The method also optionally takes a `prompt_callback` function,
278
313
  which is called after the prediction is generated.
279
314
 
280
- The method first prints a message indicating that it is predicting the prompt. It then records the start time
315
+ The method logs a message indicating that it is predicting the prompt. It then records the start time
281
316
  and uses the `connector` to generate a prediction for the `generated_prompt`. The duration of the prediction
282
317
  is calculated and stored in the `generated_prompt`.
283
318
 
@@ -297,9 +332,24 @@ class Connector:
297
332
  Raises:
298
333
  Exception: If there is an error during prediction.
299
334
  """
335
+ if generated_prompt is None or not isinstance(
336
+ generated_prompt, ConnectorPromptArguments
337
+ ):
338
+ raise ValueError(
339
+ CONNECTOR_GET_PREDICTION_ARGUMENTS_GENERATED_PROMPT_VALIDATION_ERROR
340
+ )
341
+
342
+ if connector is None or not isinstance(connector, Connector):
343
+ raise ValueError(
344
+ CONNECTOR_GET_PREDICTION_ARGUMENTS_CONNECTOR_VALIDATION_ERROR
345
+ )
346
+
300
347
  try:
301
348
  logger.info(
302
- f"Predicting prompt {generated_prompt.prompt_index} [{connector.id}]"
349
+ CONNECTOR_GET_PREDICTION_INFO.format(
350
+ connector_id=connector.id,
351
+ prompt_index=generated_prompt.prompt_index,
352
+ )
303
353
  )
304
354
 
305
355
  start_time = time.perf_counter()
@@ -308,7 +358,11 @@ class Connector:
308
358
  )
309
359
  generated_prompt.duration = time.perf_counter() - start_time
310
360
  logger.debug(
311
- f"[Prompt {generated_prompt.prompt_index}] took {generated_prompt.duration:.4f}s"
361
+ CONNECTOR_GET_PREDICTION_TIME_TAKEN_INFO.format(
362
+ connector_id=connector.id,
363
+ prompt_index=generated_prompt.prompt_index,
364
+ prompt_duration=f"{generated_prompt.duration:.4f}",
365
+ )
312
366
  )
313
367
 
314
368
  # Call prompt callback
@@ -319,17 +373,28 @@ class Connector:
319
373
  return generated_prompt
320
374
 
321
375
  except Exception as e:
322
- logger.error(f"Failed to get prediction: {str(e)}")
376
+ logger.error(
377
+ CONNECTOR_GET_PREDICTION_ERROR.format(
378
+ connector_id=connector.id,
379
+ prompt_index=generated_prompt.prompt_index,
380
+ message=str(e),
381
+ )
382
+ )
323
383
  raise e
324
384
 
325
385
  def set_system_prompt(self, system_prompt: str) -> None:
326
386
  """
327
- Assigns a new system prompt to this connector instance.
387
+ Sets a new system prompt for this connector instance.
328
388
 
329
- The system prompt serves as a preconfigured command or message that the connector can use to initiate
330
- interactions or execute specific operations.
389
+ The system prompt is a predefined message or command that the connector can use to start interactions
390
+ or perform specific tasks.
331
391
 
332
- Parameters:
392
+ Args:
333
393
  system_prompt (str): The new system prompt to set for this connector.
394
+
395
+ Raises:
396
+ ValueError: If the provided system prompt is not a string or is None.
334
397
  """
398
+ if system_prompt is None or not isinstance(system_prompt, str):
399
+ raise ValueError(CONNECTOR_SET_SYSTEM_PROMPT_VALIDATION_ERROR)
335
400
  self.system_prompt = system_prompt
@@ -1,17 +1,27 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Any
3
+ from typing import Annotated, Any
4
4
 
5
- from pydantic import BaseModel
5
+ from pydantic import BaseModel, Field
6
+
7
+ from moonshot.src.connectors.connector_response import ConnectorResponse
6
8
 
7
9
 
8
10
  class ConnectorPromptArguments(BaseModel):
9
- prompt_index: int # The index of the prompt in the dataset
11
+ class Config:
12
+ arbitrary_types_allowed = True
13
+
14
+ prompt_index: Annotated[
15
+ int, Field(strict=True, ge=0)
16
+ ] # The index of the prompt in the dataset
10
17
 
11
18
  prompt: str # The actual prompt text
12
19
 
13
20
  target: Any # The target response for the prompt
14
21
 
15
- predicted_results: Any = "" # The predicted results, default is an empty string
22
+ predicted_results: ConnectorResponse | None = (
23
+ None # The predicted results, default is None
24
+ )
16
25
 
17
- duration: float = 0.0 # The duration it took to get the results, default is 0.0
26
+ # The duration it took to get the results, must be a positive float
27
+ duration: Annotated[float, Field(strict=True, ge=0.0)] = 0.0
@@ -0,0 +1,15 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class ConnectorResponse(BaseModel):
5
+ response: str = ""
6
+ context: list = []
7
+
8
+ def to_dict(self) -> dict:
9
+ """
10
+ Converts the ConnectorResponse instance to a dictionary.
11
+
12
+ Returns:
13
+ dict: A dictionary representation of the ConnectorResponse instance.
14
+ """
15
+ return {"response": self.response, "context": self.context}
@@ -1,12 +1,20 @@
1
1
  from pathlib import Path
2
2
 
3
- from pydantic import validate_call
3
+ from pydantic import constr, validate_call
4
4
  from slugify import slugify
5
5
 
6
6
  from moonshot.src.configs.env_variables import EnvVariables
7
7
  from moonshot.src.connectors_endpoints.connector_endpoint_arguments import (
8
8
  ConnectorEndpointArguments,
9
9
  )
10
+ from moonshot.src.messages_constants import (
11
+ CONNECTOR_ENDPOINT_CREATE_ERROR,
12
+ CONNECTOR_ENDPOINT_DELETE_ERROR,
13
+ CONNECTOR_ENDPOINT_GET_AVAILABLE_ITEMS_ERROR,
14
+ CONNECTOR_ENDPOINT_READ_ERROR,
15
+ CONNECTOR_ENDPOINT_READ_INVALID,
16
+ CONNECTOR_ENDPOINT_UPDATE_ERROR,
17
+ )
10
18
  from moonshot.src.storage.storage import Storage
11
19
  from moonshot.src.utils.log import configure_logger
12
20
 
@@ -16,6 +24,7 @@ logger = configure_logger(__name__)
16
24
 
17
25
  class ConnectorEndpoint:
18
26
  @staticmethod
27
+ @validate_call
19
28
  def create(ep_args: ConnectorEndpointArguments) -> str:
20
29
  """
21
30
  Creates a new connector endpoint and stores its details as a JSON object.
@@ -47,6 +56,7 @@ class ConnectorEndpoint:
47
56
  "token": ep_args.token,
48
57
  "max_calls_per_second": ep_args.max_calls_per_second,
49
58
  "max_concurrency": ep_args.max_concurrency,
59
+ "model": ep_args.model,
50
60
  "params": ep_args.params,
51
61
  }
52
62
 
@@ -57,12 +67,12 @@ class ConnectorEndpoint:
57
67
  return ep_id
58
68
 
59
69
  except Exception as e:
60
- logger.error(f"Failed to create endpoint: {str(e)}")
70
+ logger.error(CONNECTOR_ENDPOINT_CREATE_ERROR.format(message=str(e)))
61
71
  raise e
62
72
 
63
73
  @staticmethod
64
74
  @validate_call
65
- def read(ep_id: str) -> ConnectorEndpointArguments:
75
+ def read(ep_id: constr(min_length=1)) -> ConnectorEndpointArguments:
66
76
  """
67
77
  Retrieves the details of a specified endpoint by its ID.
68
78
 
@@ -72,27 +82,24 @@ class ConnectorEndpoint:
72
82
  any other error occurs, an exception is raised with an appropriate error message.
73
83
 
74
84
  Args:
75
- ep_id (str): The unique identifier of the endpoint whose details are to be retrieved.
85
+ ep_id (constr(min_length=1)): The unique identifier of the endpoint whose details are to be retrieved.
76
86
 
77
87
  Returns:
78
88
  ConnectorEndpointArguments: An instance filled with the endpoint's details.
79
89
 
80
90
  Raises:
81
- RuntimeError: If the endpoint ID is empty or the specified endpoint does not exist.
91
+ RuntimeError: If the specified endpoint does not exist.
82
92
  Exception: For any issues encountered during the file reading or data parsing process.
83
93
  """
84
94
  try:
85
- if not ep_id:
86
- raise RuntimeError("Connector Endpoint ID is empty.")
87
-
88
95
  endpoint_details = ConnectorEndpoint._read_endpoint(ep_id)
89
96
  if not endpoint_details:
90
- raise RuntimeError(f"Endpoint with ID '{ep_id}' does not exist.")
97
+ raise RuntimeError(CONNECTOR_ENDPOINT_READ_INVALID.format(ep_id=ep_id))
91
98
 
92
99
  return ConnectorEndpointArguments(**endpoint_details)
93
100
 
94
101
  except Exception as e:
95
- logger.error(f"Failed to read endpoint: {str(e)}")
102
+ logger.error(CONNECTOR_ENDPOINT_READ_ERROR.format(message=str(e)))
96
103
  raise e
97
104
 
98
105
  @staticmethod
@@ -124,6 +131,7 @@ class ConnectorEndpoint:
124
131
  return connector_endpoint_info
125
132
 
126
133
  @staticmethod
134
+ @validate_call
127
135
  def update(ep_args: ConnectorEndpointArguments) -> bool:
128
136
  """
129
137
  Updates the endpoint information in the storage based on the provided ConnectorEndpointArguments object.
@@ -138,11 +146,10 @@ class ConnectorEndpoint:
138
146
  ep_args (ConnectorEndpointArguments): The object encapsulating the updated attributes of the endpoint.
139
147
 
140
148
  Returns:
141
- bool: Indicates whether the update operation was successful. Returns True if the update was successfully
142
- persisted to the storage; otherwise, an exception is raised.
149
+ bool: True if the update was successfully persisted to the storage; otherwise, an exception is raised.
143
150
 
144
151
  Raises:
145
- Exception: Signifies a failure in the update process, potentially due to issues with data serialization or
152
+ Exception: If the update process encounters an error, potentially due to issues with data serialization or
146
153
  storage access.
147
154
  """
148
155
  try:
@@ -160,24 +167,24 @@ class ConnectorEndpoint:
160
167
  return True
161
168
 
162
169
  except Exception as e:
163
- logger.error(f"Failed to update endpoint: {str(e)}")
170
+ logger.error(CONNECTOR_ENDPOINT_UPDATE_ERROR.format(message=str(e)))
164
171
  raise e
165
172
 
166
173
  @staticmethod
167
174
  @validate_call
168
- def delete(ep_id: str) -> bool:
175
+ def delete(ep_id: constr(min_length=1)) -> bool:
169
176
  """
170
177
  Deletes the endpoint with the specified ID.
171
178
 
172
179
  This method attempts to delete the endpoint corresponding to the given ID from the storage.
173
- If the deletion is successful, it returns True. If an error occurs, it prints an error message
180
+ If the deletion is successful, it returns True. If an error occurs, it logs an error message
174
181
  and re-raises the exception.
175
182
 
176
183
  Args:
177
- ep_id (str): The unique identifier of the endpoint to be deleted.
184
+ ep_id (constr(min_length=1)): The unique identifier of the endpoint to be deleted
178
185
 
179
186
  Returns:
180
- bool: True if the endpoint was successfully deleted.
187
+ bool: True if the endpoint was successfully deleted; otherwise, an exception is raised.
181
188
 
182
189
  Raises:
183
190
  Exception: If the deletion process encounters an error.
@@ -187,7 +194,7 @@ class ConnectorEndpoint:
187
194
  return True
188
195
 
189
196
  except Exception as e:
190
- logger.error(f"Failed to delete endpoint: {str(e)}")
197
+ logger.error(CONNECTOR_ENDPOINT_DELETE_ERROR.format(message=str(e)))
191
198
  raise e
192
199
 
193
200
  @staticmethod
@@ -204,6 +211,9 @@ class ConnectorEndpoint:
204
211
  Returns:
205
212
  tuple[list[str], list[ConnectorEndpointArguments]]: A tuple containing a list of endpoint IDs and a list of
206
213
  ConnectorEndpointArguments objects with endpoint details.
214
+
215
+ Raises:
216
+ Exception: If the process of fetching available items encounters an error.
207
217
  """
208
218
  try:
209
219
  retn_eps = []
@@ -223,5 +233,7 @@ class ConnectorEndpoint:
223
233
  return retn_eps_ids, retn_eps
224
234
 
225
235
  except Exception as e:
226
- logger.error(f"Failed to get available endpoints: {str(e)}")
236
+ logger.error(
237
+ CONNECTOR_ENDPOINT_GET_AVAILABLE_ITEMS_ERROR.format(message=str(e))
238
+ )
227
239
  raise e
@@ -22,6 +22,8 @@ class ConnectorEndpointArguments(BaseModel):
22
22
  gt=0
23
23
  ) # max_concurrency (int): The number of concurrent api calls
24
24
 
25
+ model: str # model (str): The model identifier for the LLM connector.
26
+
25
27
  params: dict # params (dict): A dictionary that contains connection specified parameters
26
28
 
27
29
  # created_date (str): The date and time the endpoint was created in isoformat without 'T'.
@@ -34,7 +36,7 @@ class ConnectorEndpointArguments(BaseModel):
34
36
 
35
37
  This method takes all the attributes of the ConnectorEndpointArguments instance and constructs a dictionary
36
38
  with attribute names as keys and their corresponding values. This includes the id, name, connector_type, uri,
37
- token, max_calls_per_second, max_concurrency, params, and created_date. This dictionary can be used for
39
+ token, max_calls_per_second, max_concurrency, model, params, and created_date. This dictionary can be used for
38
40
  serialization purposes, such as storing the endpoint information in a JSON file or sending it over a network.
39
41
 
40
42
  Returns:
@@ -49,6 +51,7 @@ class ConnectorEndpointArguments(BaseModel):
49
51
  "token": self.token,
50
52
  "max_calls_per_second": self.max_calls_per_second,
51
53
  "max_concurrency": self.max_concurrency,
54
+ "model": self.model,
52
55
  "params": self.params,
53
56
  "created_date": self.created_date,
54
57
  }