agenta 0.14.6a0__py3-none-any.whl → 0.14.7__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.

Potentially problematic release.


This version of agenta might be problematic. Click here for more details.

agenta/sdk/agenta_init.py CHANGED
@@ -1,8 +1,9 @@
1
1
  import os
2
2
  import logging
3
- from typing import Optional
3
+ from typing import Any, Optional
4
+
5
+ from .utils.globals import set_global
4
6
 
5
- from agenta.sdk.utils.globals import set_global
6
7
  from agenta.client.backend.client import AgentaApi
7
8
  from agenta.sdk.tracing.llm_tracing import Tracing
8
9
  from agenta.client.exceptions import APIRequestError
@@ -12,6 +13,18 @@ logger = logging.getLogger(__name__)
12
13
  logger.setLevel(logging.DEBUG)
13
14
 
14
15
 
16
+ BACKEND_URL_SUFFIX = os.environ.get("BACKEND_URL_SUFFIX", "api")
17
+ CLIENT_API_KEY = os.environ.get("AGENTA_API_KEY")
18
+ CLIENT_HOST = os.environ.get("AGENTA_HOST", "http://localhost")
19
+
20
+ # initialize the client with the backend url and api key
21
+ backend_url = f"{CLIENT_HOST}/{BACKEND_URL_SUFFIX}"
22
+ client = AgentaApi(
23
+ base_url=backend_url,
24
+ api_key=CLIENT_API_KEY if CLIENT_API_KEY else "",
25
+ )
26
+
27
+
15
28
  class AgentaSingleton:
16
29
  """Singleton class to save all the "global variables" for the sdk."""
17
30
 
@@ -24,21 +37,15 @@ class AgentaSingleton:
24
37
  cls._instance = super(AgentaSingleton, cls).__new__(cls)
25
38
  return cls._instance
26
39
 
27
- @property
28
- def client(self):
29
- """Builds sdk client instance.
30
-
31
- Returns:
32
- AgentaAPI: instance of agenta api backend
33
- """
34
-
35
- return AgentaApi(base_url=self.host + "/api", api_key=self.api_key)
36
-
37
40
  def init(
38
41
  self,
42
+ app_name: Optional[str] = None,
43
+ base_name: Optional[str] = None,
44
+ api_key: Optional[str] = None,
45
+ base_id: Optional[str] = None,
39
46
  app_id: Optional[str] = None,
40
47
  host: Optional[str] = None,
41
- api_key: Optional[str] = None,
48
+ **kwargs: Any,
42
49
  ) -> None:
43
50
  """Main function to initialize the singleton.
44
51
 
@@ -46,44 +53,57 @@ class AgentaSingleton:
46
53
  the function will look for them in environment variables.
47
54
 
48
55
  Args:
49
- app_id (Optional[str]): ID of the Agenta application. Defaults to None. If not provided, will look for "AGENTA_APP_NAME" in environment variables.
56
+ app_name (Optional[str]): Name of the Agenta application. Defaults to None. If not provided, will look for "AGENTA_APP_NAME" in environment variables.
57
+ base_name (Optional[str]): Base name for the Agenta setup. Defaults to None. If not provided, will look for "AGENTA_BASE_NAME" in environment variables.
50
58
  host (Optional[str]): Host name of the backend server. Defaults to None. If not provided, will look for "AGENTA_HOST" in environment variables.
51
- api_key (Optional[str]): API Key to use with the host of the backend server.
52
59
  kwargs (Any): Additional keyword arguments.
53
60
 
54
61
  Raises:
55
62
  ValueError: If `app_name`, `base_name`, or `host` are not specified either as arguments or in the environment variables.
56
63
  """
57
-
58
- self.api_key = api_key or os.environ.get("AGENTA_API_KEY")
59
- self.host = host or os.environ.get("AGENTA_HOST", "http://localhost")
60
-
61
- app_id = app_id or os.environ.get("AGENTA_APP_ID")
62
- if not app_id:
63
- raise ValueError("App ID must be specified.")
64
-
65
- base_id = os.environ.get("AGENTA_BASE_ID")
66
- base_name = os.environ.get("AGENTA_BASE_NAME")
67
- if base_id is None and (app_id is None or base_name is None):
68
- print(
69
- f"Warning: Your configuration will not be saved permanently since app_name and base_name are not provided."
70
- )
71
- else:
72
- try:
73
- base_id = self.get_app_base(app_id, base_name) # type: ignore
74
- except Exception as ex:
75
- raise APIRequestError(
76
- f"Failed to get base id and/or app_id from the server with error: {ex}"
64
+ if app_name is None:
65
+ app_name = os.environ.get("AGENTA_APP_NAME")
66
+ if base_name is None:
67
+ base_name = os.environ.get("AGENTA_BASE_NAME")
68
+ if api_key is None:
69
+ api_key = os.environ.get("AGENTA_API_KEY")
70
+ if base_id is None:
71
+ base_id = os.environ.get("AGENTA_BASE_ID")
72
+ if host is None:
73
+ host = os.environ.get("AGENTA_HOST", "http://localhost")
74
+
75
+ if base_id is None:
76
+ if app_name is None or base_name is None:
77
+ print(
78
+ f"Warning: Your configuration will not be saved permanently since app_name and base_name are not provided."
77
79
  )
80
+ else:
81
+ try:
82
+ app_id = self.get_app(app_name)
83
+ base_id = self.get_app_base(app_id, base_name)
84
+ except Exception as ex:
85
+ raise APIRequestError(
86
+ f"Failed to get base id and/or app_id from the server with error: {ex}"
87
+ )
78
88
 
79
- self.app_id = app_id
80
89
  self.base_id = base_id
90
+ self.host = host
91
+ self.app_id = os.environ.get("AGENTA_APP_ID") if app_id is None else app_id
81
92
  self.variant_id = os.environ.get("AGENTA_VARIANT_ID")
82
93
  self.variant_name = os.environ.get("AGENTA_VARIANT_NAME")
94
+ self.api_key = api_key
83
95
  self.config = Config(base_id=base_id, host=host)
84
96
 
97
+ def get_app(self, app_name: str) -> str:
98
+ apps = client.apps.list_apps(app_name=app_name)
99
+ if len(apps) == 0:
100
+ raise APIRequestError(f"App with name {app_name} not found")
101
+
102
+ app_id = apps[0].app_id
103
+ return app_id
104
+
85
105
  def get_app_base(self, app_id: str, base_name: str) -> str:
86
- bases = self.client.bases.list_bases(app_id=app_id, base_name=base_name)
106
+ bases = client.bases.list_bases(app_id=app_id, base_name=base_name)
87
107
  if len(bases) == 0:
88
108
  raise APIRequestError(f"No base was found for the app {app_id}")
89
109
  return bases[0].base_id
@@ -102,23 +122,11 @@ class Config:
102
122
  def __init__(self, base_id, host):
103
123
  self.base_id = base_id
104
124
  self.host = host
105
-
106
125
  if base_id is None or host is None:
107
126
  self.persist = False
108
127
  else:
109
128
  self.persist = True
110
129
 
111
- @property
112
- def client(self):
113
- """Builds sdk client instance.
114
-
115
- Returns:
116
- AgentaAPI: instance of agenta api backend
117
- """
118
-
119
- sdk_client = SDKClient(api_key=self.api_key, host=self.host) # type: ignore
120
- return sdk_client._build_sdk_client()
121
-
122
130
  def register_default(self, overwrite=False, **kwargs):
123
131
  """alias for default"""
124
132
  return self.default(overwrite=overwrite, **kwargs)
@@ -149,7 +157,7 @@ class Config:
149
157
  if not self.persist:
150
158
  return
151
159
  try:
152
- self.client.configs.save_config(
160
+ client.configs.save_config(
153
161
  base_id=self.base_id,
154
162
  config_name=config_name,
155
163
  parameters=kwargs,
@@ -160,9 +168,7 @@ class Config:
160
168
  "Failed to push the configuration to the server with error: " + str(ex)
161
169
  )
162
170
 
163
- def pull(
164
- self, config_name: str = "default", environment_name: Optional[str] = None
165
- ):
171
+ def pull(self, config_name: str = "default", environment_name: str = None):
166
172
  """Pulls the parameters for the app variant from the server and sets them to the config"""
167
173
  if not self.persist and (
168
174
  config_name != "default" or environment_name is not None
@@ -173,12 +179,12 @@ class Config:
173
179
  if self.persist:
174
180
  try:
175
181
  if environment_name:
176
- config = self.client.configs.get_config(
182
+ config = client.configs.get_config(
177
183
  base_id=self.base_id, environment_name=environment_name
178
184
  )
179
185
 
180
186
  else:
181
- config = self.client.configs.get_config(
187
+ config = client.configs.get_config(
182
188
  base_id=self.base_id,
183
189
  config_name=config_name,
184
190
  )
@@ -212,22 +218,15 @@ class Config:
212
218
  setattr(self, key, value)
213
219
 
214
220
 
215
- def init(
216
- app_id: Optional[str] = None,
217
- host: Optional[str] = None,
218
- api_key: Optional[str] = None,
219
- ):
221
+ def init(app_name=None, base_name=None, **kwargs):
220
222
  """Main function to be called by the user to initialize the sdk.
221
223
 
222
224
  Args:
223
- app_id (str): The Id of the app.
224
- host (str): The host of the backend server.
225
- api_key (str): The API key to use for the backend server.
225
+ app_name: _description_. Defaults to None.
226
+ base_name: _description_. Defaults to None.
226
227
  """
227
-
228
228
  singleton = AgentaSingleton()
229
-
230
- singleton.init(app_id=app_id, host=host, api_key=api_key)
229
+ singleton.init(app_name=app_name, base_name=base_name, **kwargs)
231
230
  set_global(setup=singleton.setup, config=singleton.config)
232
231
 
233
232
 
@@ -236,7 +235,7 @@ def llm_tracing(max_workers: Optional[int] = None) -> Tracing:
236
235
 
237
236
  singleton = AgentaSingleton()
238
237
  return Tracing(
239
- base_url=singleton.host, # type: ignore
238
+ base_url=singleton.host,
240
239
  app_id=singleton.app_id, # type: ignore
241
240
  variant_id=singleton.variant_id, # type: ignore
242
241
  variant_name=singleton.variant_name,
@@ -0,0 +1,41 @@
1
+ # Stdlib Imports
2
+ import inspect
3
+ from functools import wraps
4
+
5
+ # Own Imports
6
+ import agenta as ag
7
+
8
+
9
+ def span(type: str):
10
+ """Decorator to automatically start and end spans."""
11
+
12
+ tracing = ag.llm_tracing()
13
+
14
+ def decorator(func):
15
+ @wraps(func)
16
+ async def wrapper(*args, **kwargs):
17
+ result = None
18
+ span = tracing.start_span(
19
+ name=func.__name__,
20
+ input=kwargs,
21
+ spankind=type,
22
+ )
23
+ try:
24
+ is_coroutine_function = inspect.iscoroutinefunction(func)
25
+ if is_coroutine_function:
26
+ result = await func(*args, **kwargs)
27
+ else:
28
+ result = func(*args, **kwargs)
29
+ tracing.update_span_status(span=span, value="OK")
30
+ except Exception as e:
31
+ result = str(e)
32
+ tracing.update_span_status(span=span, value="ERROR")
33
+ finally:
34
+ if not isinstance(result, dict):
35
+ result = {"message": result}
36
+ tracing.end_span(outputs=result, span=span)
37
+ return result
38
+
39
+ return wrapper
40
+
41
+ return decorator
@@ -1,5 +1,4 @@
1
1
  # Stdlib Imports
2
- from threading import Lock
3
2
  from datetime import datetime, timezone
4
3
  from typing import Optional, Dict, Any, List, Union
5
4
 
@@ -14,43 +13,10 @@ from agenta.client.backend.types.create_span import CreateSpan, SpanKind, SpanSt
14
13
  from bson.objectid import ObjectId
15
14
 
16
15
 
17
- class SingletonMeta(type):
18
- """
19
- Thread-safe implementation of Singleton.
20
- """
21
-
22
- _instances = {} # type: ignore
23
-
24
- # We need the lock mechanism to synchronize threads \
25
- # during the initial access to the Singleton object.
26
- _lock: Lock = Lock()
16
+ class Tracing(object):
17
+ """Agenta llm tracing object.
27
18
 
28
- def __call__(cls, *args, **kwargs):
29
- """
30
- Possible changes to the value of the `__init__` argument do not affect
31
- the returned instance.
32
- """
33
- # Now, imagine that the program has just been launched. Since there's no
34
- # Singleton instance yet, multiple threads can simultaneously pass the
35
- # previous conditional and reach this point almost at the same time. The
36
- # first of them will acquire lock and will proceed further, while the
37
- # rest will wait here.
38
- with cls._lock:
39
- # The first thread to acquire the lock, reaches this conditional,
40
- # goes inside and creates the Singleton instance. Once it leaves the
41
- # lock block, a thread that might have been waiting for the lock
42
- # release may then enter this section. But since the Singleton field
43
- # is already initialized, the thread won't create a new object.
44
- if cls not in cls._instances:
45
- instance = super().__call__(*args, **kwargs)
46
- cls._instances[cls] = instance
47
- return cls._instances[cls]
48
-
49
-
50
- class Tracing(metaclass=SingletonMeta):
51
- """The `Tracing` class is an agent for LLM tracing with specific initialization arguments.
52
-
53
- __init__ args:
19
+ Args:
54
20
  base_url (str): The URL of the backend host
55
21
  api_key (str): The API Key of the backend host
56
22
  tasks_manager (TaskQueue): The tasks manager dedicated to handling asynchronous tasks
@@ -58,11 +24,18 @@ class Tracing(metaclass=SingletonMeta):
58
24
  max_workers (int): The maximum number of workers to run tracing
59
25
  """
60
26
 
27
+ _instance = None
28
+
29
+ def __new__(cls, *args, **kwargs):
30
+ if not cls._instance:
31
+ cls._instance = super().__new__(cls)
32
+ return cls._instance
33
+
61
34
  def __init__(
62
35
  self,
63
36
  base_url: str,
64
37
  app_id: str,
65
- variant_id: Optional[str] = None,
38
+ variant_id: str,
66
39
  variant_name: Optional[str] = None,
67
40
  api_key: Optional[str] = None,
68
41
  max_workers: Optional[int] = None,
@@ -121,7 +94,7 @@ class Tracing(metaclass=SingletonMeta):
121
94
  self.tags.extend(tags)
122
95
 
123
96
  def start_parent_span(
124
- self, name: str, inputs: Dict[str, Any], config: Dict[str, Any] = {}, **kwargs
97
+ self, name: str, inputs: Dict[str, Any], config: Dict[str, Any], **kwargs
125
98
  ):
126
99
  trace_id = self._create_trace_id()
127
100
  span_id = self._create_span_id()
@@ -106,7 +106,9 @@ class TaskQueue(object):
106
106
  future.result()
107
107
  except Exception as exc:
108
108
  self._logger.error(f"Error running task: {str(exc)}")
109
- self._logger.error(f"Recording {task.coroutine_type} status to ERROR.")
109
+ self._logger.error(
110
+ f"Recording trace {task.coroutine_type} status to ERROR."
111
+ )
110
112
  break
111
113
  finally:
112
114
  self.tasks.task_done()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: agenta
3
- Version: 0.14.6a0
3
+ Version: 0.14.7
4
4
  Summary: The SDK for agenta is an open-source LLMOps platform.
5
5
  Home-page: https://agenta.ai
6
6
  Keywords: LLMOps,LLM,evaluation,prompt engineering
@@ -1,9 +1,9 @@
1
- agenta/__init__.py,sha256=q83im-TuPtSRJVOQIAH59EuH_qNIGXpbcNugNfXI4mc,666
1
+ agenta/__init__.py,sha256=rCZ-mUOGnyKQpfWQFzXIEFX7KBlGC3qFMighdIVJgDc,610
2
2
  agenta/cli/evaluation_commands.py,sha256=fs6492tprPId9p8eGO02Xy-NCBm2RZNJLZWcUxugwd8,474
3
3
  agenta/cli/helper.py,sha256=vRxHyeNaltzNIGrfU2vO0H28_rXDzx9QqIZ_S-W6zL4,6212
4
4
  agenta/cli/main.py,sha256=GgYu6UsrnHbqPV7zPlO14b61IyaDiTIjGMYQS9DlqC4,9551
5
5
  agenta/cli/telemetry.py,sha256=GaFFRsE_NtrcSSJ10r2jhgFs5Sk8gf2C09Ox3gOr3eU,1317
6
- agenta/cli/variant_commands.py,sha256=9Ac2gB_2wokabxEgtY85xbYMt078JFfOXyi6GSkZ3rI,17268
6
+ agenta/cli/variant_commands.py,sha256=clqmv-UL2UKjOSVGn1icOXSEJ3EMf43-OphuHNWknCQ,17286
7
7
  agenta/cli/variant_configs.py,sha256=PLiuMKadVzs6Gi2uYaT0pZzyULNHDXaTMDWboqpwWdU,1293
8
8
  agenta/client/Readme.md,sha256=zWJ6VMYCG124op5RcqgWBdJdlGkGQ2rPLk9F32rWvqo,2756
9
9
  agenta/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -126,18 +126,17 @@ agenta/docker/docker-assets/entrypoint.sh,sha256=29XK8VQjQsx4hN2j-4JDy-6kQb5y4LC
126
126
  agenta/docker/docker-assets/lambda_function.py,sha256=h4UZSSfqwpfsCgERv6frqwm_4JrYu9rLz3I-LxCfeEg,83
127
127
  agenta/docker/docker-assets/main.py,sha256=7MI-21n81U7N7A0GxebNi0cmGWtJKcR2sPB6FcH2QfA,251
128
128
  agenta/docker/docker_utils.py,sha256=5uHMCzXkCvIsDdEiwbnnn97KkzsFbBvyMwogCsv_Z5U,3509
129
- agenta/sdk/__init__.py,sha256=TyVUf1LEKLenwS_QAtqVDPCW1s8kLHipD6WYjMD4T48,632
130
- agenta/sdk/agenta_init.py,sha256=r28xgllqHe0Zs3Xz4UU7DoBMLF1tbPEbaqDi5irSiC8,8638
129
+ agenta/sdk/__init__.py,sha256=jmeLRuXrew02ZruODZYIu4kpw0S8vV6JhMPQWFGtj30,648
130
+ agenta/sdk/agenta_decorator.py,sha256=6vz0G3YCRKRzK8JrQFyy8c2RIXy2kVMwyxTS093_8vQ,17296
131
+ agenta/sdk/agenta_init.py,sha256=wDfStpe8_3ZXRLtikarwDKI_VpA1YW4eIz_3fXq39is,9044
131
132
  agenta/sdk/client.py,sha256=trKyBOYFZRk0v5Eptxvh87yPf50Y9CqY6Qgv4Fy-VH4,2142
132
133
  agenta/sdk/context.py,sha256=q-PxL05-I84puunUAs9LGsffEXcYhDxhQxjuOz2vK90,901
133
- agenta/sdk/decorators/base.py,sha256=9aNdX5h8a2mFweuhdO-BQPwXGKY9ONPIdLRhSGAGMfY,217
134
- agenta/sdk/decorators/llm_entrypoint.py,sha256=VU41C20ocPWm2pT5RCGpgj4cpT_ZRsgLmVteRgCx0sg,18586
135
- agenta/sdk/decorators/tracing.py,sha256=5Y2Jb0v07BUDlJyBuIDCZ3oIcF1Mp6rNCqQzDIW3Skk,3299
136
134
  agenta/sdk/router.py,sha256=0sbajvn5C7t18anH6yNo7-oYxldHnYfwcbmQnIXBePw,269
137
135
  agenta/sdk/tracing/context_manager.py,sha256=HskDaiORoOhjeN375gm05wYnieQzh5UnoIsnSAHkAyc,252
138
- agenta/sdk/tracing/llm_tracing.py,sha256=s8sHojV1ncYEg1uAWcm3BsfPd_6yaOPvB03Tq1FnEMU,8709
136
+ agenta/sdk/tracing/decorators.py,sha256=ujtU8gf3GDoHYuLTfEYK_2eIYZ-1oX5dpv02Mf4l_II,1191
137
+ agenta/sdk/tracing/llm_tracing.py,sha256=UiotJ56EFA3VPt7LREkcK2w51D9-0T1QNvBy4zNWEdY,7348
139
138
  agenta/sdk/tracing/logger.py,sha256=4zG9c51p8xPdKA5SL8MOgBfkpCnBSuV6JfWiXO0A7oc,473
140
- agenta/sdk/tracing/tasks_manager.py,sha256=ROrWIaqS2J2HHiJtRWiHKlLY8CCsqToP5VeXu7mamck,3748
139
+ agenta/sdk/tracing/tasks_manager.py,sha256=XVGBEOwmHa6KcCC0PApk0_bZ0Ilk2ESuduNObB1rw2s,3792
141
140
  agenta/sdk/types.py,sha256=Mn0yBlHh_Yr_5oQXUfsYI3V7sJAVWkJgkxEOBDOOMS0,5852
142
141
  agenta/sdk/utils/globals.py,sha256=lpgflY8xovZJtHfJf41dbNCZGwx07YNkG9ldruv6xoI,360
143
142
  agenta/sdk/utils/helper/openai_cost.py,sha256=1VkgvucDnNZm1pTfcVLz9icWunntp1d7zwMmnviy3Uw,5877
@@ -157,7 +156,7 @@ agenta/templates/simple_prompt/app.py,sha256=kODgF6lhzsaJPdgL5b21bUki6jkvqjWZzWR
157
156
  agenta/templates/simple_prompt/env.example,sha256=g9AE5bYcGPpxawXMJ96gh8oenEPCHTabsiOnfQo3c5k,70
158
157
  agenta/templates/simple_prompt/requirements.txt,sha256=ywRglRy7pPkw8bljmMEJJ4aOOQKrt9FGKULZ-DGkoBU,23
159
158
  agenta/templates/simple_prompt/template.toml,sha256=DQBtRrF4GU8LBEXOZ-GGuINXMQDKGTEG5y37tnvIUIE,60
160
- agenta-0.14.6a0.dist-info/METADATA,sha256=ckpAYSrWyEdhVcfNPPTus0gpwFqU1boT3YslWPUncM4,26472
161
- agenta-0.14.6a0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
162
- agenta-0.14.6a0.dist-info/entry_points.txt,sha256=PDiu8_8AsL7ibU9v4iNoOKR1S7F2rdxjlEprjM9QOgo,46
163
- agenta-0.14.6a0.dist-info/RECORD,,
159
+ agenta-0.14.7.dist-info/METADATA,sha256=nYB7z6_Vl_CXojP9cWfb7Vpgou6c9AV-YK3X6_DP6T0,26470
160
+ agenta-0.14.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
161
+ agenta-0.14.7.dist-info/entry_points.txt,sha256=PDiu8_8AsL7ibU9v4iNoOKR1S7F2rdxjlEprjM9QOgo,46
162
+ agenta-0.14.7.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- # Stdlib Imports
2
- from typing import Any, Callable
3
-
4
-
5
- class BaseDecorator:
6
- def __init__(self):
7
- pass
8
-
9
- def __call__(self, func: Callable[..., Any]) -> Callable[..., Any]:
10
- raise NotImplementedError