agenta 0.14.14a1__py3-none-any.whl → 0.15.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.

Potentially problematic release.


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

agenta/__init__.py CHANGED
@@ -1,5 +1,4 @@
1
1
  from .sdk.utils.preinit import PreInitObject
2
- from .sdk.agenta_decorator import app, entrypoint
3
2
  from .sdk.context import get_contexts, save_context
4
3
  from .sdk.types import (
5
4
  Context,
@@ -14,9 +13,13 @@ from .sdk.types import (
14
13
  FileInputURL,
15
14
  BinaryParam,
16
15
  )
17
- from .sdk.tracing.decorators import span
18
- from .sdk.agenta_init import Config, init, llm_tracing
16
+ from .sdk.tracing.llm_tracing import Tracing
17
+ from .sdk.decorators.tracing import instrument
18
+ from .sdk.decorators.llm_entrypoint import entrypoint, app
19
+ from .sdk.agenta_init import Config, AgentaSingleton, init
19
20
  from .sdk.utils.helper.openai_cost import calculate_token_usage
20
21
  from .sdk.client import Agenta
21
22
 
22
23
  config = PreInitObject("agenta.config", Config)
24
+ DEFAULT_AGENTA_SINGLETON_INSTANCE = AgentaSingleton()
25
+ tracing = DEFAULT_AGENTA_SINGLETON_INSTANCE.tracing # type: ignore
@@ -56,9 +56,9 @@ class AgentaApi:
56
56
  self._client_wrapper = SyncClientWrapper(
57
57
  base_url=base_url,
58
58
  api_key=api_key,
59
- httpx_client=httpx.Client(timeout=timeout)
60
- if httpx_client is None
61
- else httpx_client,
59
+ httpx_client=(
60
+ httpx.Client(timeout=timeout) if httpx_client is None else httpx_client
61
+ ),
62
62
  )
63
63
  self.observability = ObservabilityClient(client_wrapper=self._client_wrapper)
64
64
  self.apps = AppsClient(client_wrapper=self._client_wrapper)
@@ -1037,9 +1037,11 @@ class AsyncAgentaApi:
1037
1037
  self._client_wrapper = AsyncClientWrapper(
1038
1038
  base_url=base_url,
1039
1039
  api_key=api_key,
1040
- httpx_client=httpx.AsyncClient(timeout=timeout)
1041
- if httpx_client is None
1042
- else httpx_client,
1040
+ httpx_client=(
1041
+ httpx.AsyncClient(timeout=timeout)
1042
+ if httpx_client is None
1043
+ else httpx_client
1044
+ ),
1043
1045
  )
1044
1046
  self.observability = AsyncObservabilityClient(
1045
1047
  client_wrapper=self._client_wrapper
@@ -53,6 +53,6 @@ class CreateSpan(pydantic.BaseModel):
53
53
  return super().dict(**kwargs_with_defaults)
54
54
 
55
55
  class Config:
56
- frozen = True
56
+ frozen = False
57
57
  smart_union = True
58
58
  json_encoders = {dt.datetime: serialize_datetime}
@@ -2,7 +2,7 @@ FROM public.ecr.aws/s2t9a1r1/agentaai/lambda_templates_public:main
2
2
 
3
3
  COPY requirements.txt ${LAMBDA_TASK_ROOT}
4
4
  RUN pip install --no-cache-dir --disable-pip-version-check -U agenta
5
- RUN pip install --no-cache-dir --disable-pip-version-check -r requirements.txt
5
+ RUN pip install --no-cache-dir --disable-pip-version-check -U -r requirements.txt
6
6
  RUN pip install --no-cache-dir --disable-pip-version-check mangum
7
7
  COPY . ${LAMBDA_TASK_ROOT}
8
8
 
agenta/sdk/__init__.py CHANGED
@@ -1,6 +1,4 @@
1
1
  from .utils.preinit import PreInitObject # always the first import!
2
- from . import agenta_decorator, context, types, utils # noqa: F401
3
- from .agenta_decorator import app, entrypoint
4
2
  from .context import get_contexts, save_context
5
3
  from .types import (
6
4
  Context,
@@ -15,9 +13,13 @@ from .types import (
15
13
  FileInputURL,
16
14
  BinaryParam,
17
15
  )
18
- from .tracing.decorators import span
19
- from .agenta_init import Config, init, llm_tracing
16
+ from .tracing.llm_tracing import Tracing
17
+ from .decorators.tracing import instrument
18
+ from .decorators.llm_entrypoint import entrypoint, app
19
+ from .agenta_init import Config, AgentaSingleton, init
20
20
  from .utils.helper.openai_cost import calculate_token_usage
21
21
 
22
22
 
23
23
  config = PreInitObject("agenta.config", Config)
24
+ DEFAULT_AGENTA_SINGLETON_INSTANCE = AgentaSingleton()
25
+ tracing = DEFAULT_AGENTA_SINGLETON_INSTANCE.tracing # type: ignore
agenta/sdk/agenta_init.py CHANGED
@@ -1,9 +1,9 @@
1
1
  import os
2
2
  import logging
3
- from typing import Any, Optional
4
-
5
- from .utils.globals import set_global
3
+ import toml
4
+ from typing import Optional
6
5
 
6
+ from agenta.sdk.utils.globals import set_global
7
7
  from agenta.client.backend.client import AgentaApi
8
8
  from agenta.sdk.tracing.llm_tracing import Tracing
9
9
  from agenta.client.exceptions import APIRequestError
@@ -13,119 +13,97 @@ logger = logging.getLogger(__name__)
13
13
  logger.setLevel(logging.DEBUG)
14
14
 
15
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
-
28
16
  class AgentaSingleton:
29
17
  """Singleton class to save all the "global variables" for the sdk."""
30
18
 
31
19
  _instance = None
32
20
  setup = None
33
21
  config = None
22
+ tracing: Optional[Tracing] = None
34
23
 
35
24
  def __new__(cls):
36
25
  if not cls._instance:
37
26
  cls._instance = super(AgentaSingleton, cls).__new__(cls)
38
27
  return cls._instance
39
28
 
29
+ @property
30
+ def client(self):
31
+ """API Backend client.
32
+
33
+ Returns:
34
+ AgentaAPI: instance of agenta api backend
35
+ """
36
+
37
+ return AgentaApi(base_url=self.host + "/api", api_key=self.api_key)
38
+
40
39
  def init(
41
40
  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,
46
41
  app_id: Optional[str] = None,
47
42
  host: Optional[str] = None,
48
- **kwargs: Any,
43
+ api_key: Optional[str] = None,
44
+ config_fname: Optional[str] = None,
49
45
  ) -> None:
50
46
  """Main function to initialize the singleton.
51
47
 
52
- Initializes the singleton with the given `app_name`, `base_name`, and `host`. If any of these arguments are not provided,
53
- the function will look for them in environment variables.
48
+ Initializes the singleton with the given `app_id`, `host`, and `api_key`. The order of precedence for these variables is:
49
+ 1. Explicit argument provided in the function call.
50
+ 2. Value from the configuration file specified by `config_fname`.
51
+ 3. Environment variables.
52
+
53
+ Examples:
54
+ ag.init(app_id="xxxx", api_key="xxx")
55
+ ag.init(config_fname="config.toml")
56
+ ag.init() #assuming env vars are set
54
57
 
55
58
  Args:
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.
58
- host (Optional[str]): Host name of the backend server. Defaults to None. If not provided, will look for "AGENTA_HOST" in environment variables.
59
- kwargs (Any): Additional keyword arguments.
59
+ app_id (Optional[str]): ID of the Agenta application. Defaults to None. If not provided, will look for "app_id" in the config file, then "AGENTA_APP_ID" in environment variables.
60
+ host (Optional[str]): Host name of the backend server. Defaults to None. If not provided, will look for "backend_host" in the config file, then "AGENTA_HOST" in environment variables.
61
+ api_key (Optional[str]): API Key to use with the host of the backend server. Defaults to None. If not provided, will look for "api_key" in the config file, then "AGENTA_API_KEY" in environment variables.
62
+ config_fname (Optional[str]): Path to the configuration file (relative or absolute). Defaults to None.
60
63
 
61
64
  Raises:
62
- ValueError: If `app_name`, `base_name`, or `host` are not specified either as arguments or in the environment variables.
63
- """
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."
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
- )
88
-
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
92
- self.variant_id = os.environ.get("AGENTA_VARIANT_ID")
93
- self.variant_name = os.environ.get("AGENTA_VARIANT_NAME")
94
- self.api_key = api_key
95
- self.config = Config(base_id=base_id, host=host)
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
-
105
- def get_app_base(self, app_id: str, base_name: str) -> str:
106
- bases = client.bases.list_bases(app_id=app_id, base_name=base_name)
107
- if len(bases) == 0:
108
- raise APIRequestError(f"No base was found for the app {app_id}")
109
- return bases[0].base_id
110
-
111
- def get_current_config(self):
112
- """
113
- Retrieves the current active configuration
65
+ ValueError: If `app_id` is not specified either as an argument, in the config file, or in the environment variables.
114
66
  """
67
+ config = {}
68
+ if config_fname:
69
+ config = toml.load(config_fname)
70
+
71
+ self.app_id = app_id or config.get("app_id") or os.environ.get("AGENTA_APP_ID")
72
+ self.host = (
73
+ host
74
+ or config.get("backend_host")
75
+ or os.environ.get("AGENTA_HOST", "https://cloud.agenta.ai")
76
+ )
77
+ self.api_key = (
78
+ api_key or config.get("api_key") or os.environ.get("AGENTA_API_KEY")
79
+ )
80
+
81
+ if not self.app_id:
82
+ raise ValueError(
83
+ "App ID must be specified. You can provide it in one of the following ways:\n"
84
+ "1. As an argument when calling ag.init(app_id='your_app_id').\n"
85
+ "2. In the configuration file specified by config_fname.\n"
86
+ "3. As an environment variable 'AGENTA_APP_ID'."
87
+ )
88
+ self.base_id = os.environ.get("AGENTA_BASE_ID")
89
+ if self.base_id is None:
90
+ print(
91
+ "Warning: Your configuration will not be saved permanently since base_id is not provided."
92
+ )
115
93
 
116
- if self._config_data is None:
117
- raise RuntimeError("AgentaSingleton has not been initialized")
118
- return self._config_data
94
+ self.config = Config(base_id=self.base_id, host=self.host) # type: ignore
119
95
 
120
96
 
121
97
  class Config:
122
- def __init__(self, base_id, host):
98
+ def __init__(self, base_id: str, host: str, api_key: str = ""):
123
99
  self.base_id = base_id
124
100
  self.host = host
101
+
125
102
  if base_id is None or host is None:
126
103
  self.persist = False
127
104
  else:
128
105
  self.persist = True
106
+ self.client = AgentaApi(base_url=self.host + "/api", api_key=api_key)
129
107
 
130
108
  def register_default(self, overwrite=False, **kwargs):
131
109
  """alias for default"""
@@ -144,7 +122,7 @@ class Config:
144
122
  self.push(config_name="default", overwrite=overwrite, **kwargs)
145
123
  except Exception as ex:
146
124
  logger.warning(
147
- "Unable to push the default configuration to the server." + str(ex)
125
+ "Unable to push the default configuration to the server. %s", str(ex)
148
126
  )
149
127
 
150
128
  def push(self, config_name: str, overwrite=True, **kwargs):
@@ -157,7 +135,7 @@ class Config:
157
135
  if not self.persist:
158
136
  return
159
137
  try:
160
- client.configs.save_config(
138
+ self.client.configs.save_config(
161
139
  base_id=self.base_id,
162
140
  config_name=config_name,
163
141
  parameters=kwargs,
@@ -165,38 +143,40 @@ class Config:
165
143
  )
166
144
  except Exception as ex:
167
145
  logger.warning(
168
- "Failed to push the configuration to the server with error: " + str(ex)
146
+ "Failed to push the configuration to the server with error: %s", ex
169
147
  )
170
148
 
171
- def pull(self, config_name: str = "default", environment_name: str = None):
149
+ def pull(
150
+ self, config_name: str = "default", environment_name: Optional[str] = None
151
+ ):
172
152
  """Pulls the parameters for the app variant from the server and sets them to the config"""
173
153
  if not self.persist and (
174
154
  config_name != "default" or environment_name is not None
175
155
  ):
176
- raise Exception(
156
+ raise ValueError(
177
157
  "Cannot pull the configuration from the server since the app_name and base_name are not provided."
178
158
  )
179
159
  if self.persist:
180
160
  try:
181
161
  if environment_name:
182
- config = client.configs.get_config(
162
+ config = self.client.configs.get_config(
183
163
  base_id=self.base_id, environment_name=environment_name
184
164
  )
185
165
 
186
166
  else:
187
- config = client.configs.get_config(
167
+ config = self.client.configs.get_config(
188
168
  base_id=self.base_id,
189
169
  config_name=config_name,
190
170
  )
191
171
  except Exception as ex:
192
172
  logger.warning(
193
- "Failed to pull the configuration from the server with error: "
194
- + str(ex)
173
+ "Failed to pull the configuration from the server with error: %s",
174
+ str(ex),
195
175
  )
196
176
  try:
197
177
  self.set(**{"current_version": config.current_version, **config.parameters})
198
178
  except Exception as ex:
199
- logger.warning("Failed to set the configuration with error: " + str(ex))
179
+ logger.warning("Failed to set the configuration with error: %s", str(ex))
200
180
 
201
181
  def all(self):
202
182
  """Returns all the parameters for the app variant"""
@@ -204,7 +184,15 @@ class Config:
204
184
  k: v
205
185
  for k, v in self.__dict__.items()
206
186
  if k
207
- not in ["app_name", "base_name", "host", "base_id", "api_key", "persist"]
187
+ not in [
188
+ "app_name",
189
+ "base_name",
190
+ "host",
191
+ "base_id",
192
+ "api_key",
193
+ "persist",
194
+ "client",
195
+ ]
208
196
  }
209
197
 
210
198
  # function to set the parameters for the app variant
@@ -217,28 +205,52 @@ class Config:
217
205
  for key, value in kwargs.items():
218
206
  setattr(self, key, value)
219
207
 
208
+ def dump(self):
209
+ """Returns all the information about the current version in the configuration.
220
210
 
221
- def init(app_name=None, base_name=None, **kwargs):
222
- """Main function to be called by the user to initialize the sdk.
211
+ Raises:
212
+ NotImplementedError: _description_
213
+ """
223
214
 
224
- Args:
225
- app_name: _description_. Defaults to None.
226
- base_name: _description_. Defaults to None.
227
- """
228
- singleton = AgentaSingleton()
229
- singleton.init(app_name=app_name, base_name=base_name, **kwargs)
230
- set_global(setup=singleton.setup, config=singleton.config)
215
+ raise NotImplementedError()
231
216
 
232
217
 
233
- def llm_tracing(max_workers: Optional[int] = None) -> Tracing:
234
- """Function to start llm tracing."""
218
+ def init(
219
+ app_id: Optional[str] = None,
220
+ host: Optional[str] = None,
221
+ api_key: Optional[str] = None,
222
+ config_fname: Optional[str] = None,
223
+ max_workers: Optional[int] = None,
224
+ ):
225
+ """Main function to initialize the agenta sdk.
226
+
227
+ Initializes agenta with the given `app_id`, `host`, and `api_key`. The order of precedence for these variables is:
228
+ 1. Explicit argument provided in the function call.
229
+ 2. Value from the configuration file specified by `config_fname`.
230
+ 3. Environment variables.
231
+
232
+ - `app_id` is a required parameter (to be specified in one of the above ways)
233
+ - `host` is optional and defaults to "https://cloud.agenta.ai"
234
+ - `api_key` is optional and defaults to "". It is required only when using cloud or enterprise version of agenta.
235
+
236
+
237
+ Args:
238
+ app_id (Optional[str]): ID of the Agenta application. Defaults to None. If not provided, will look for "app_id" in the config file, then "AGENTA_APP_ID" in environment variables.
239
+ host (Optional[str]): Host name of the backend server. Defaults to None. If not provided, will look for "backend_host" in the config file, then "AGENTA_HOST" in environment variables.
240
+ api_key (Optional[str]): API Key to use with the host of the backend server. Defaults to None. If not provided, will look for "api_key" in the config file, then "AGENTA_API_KEY" in environment variables.
241
+ config_fname (Optional[str]): Path to the configuration file. Defaults to None.
242
+
243
+ Raises:
244
+ ValueError: If `app_id` is not specified either as an argument, in the config file, or in the environment variables.
245
+ """
235
246
 
236
247
  singleton = AgentaSingleton()
237
- return Tracing(
238
- base_url=singleton.host,
248
+
249
+ singleton.init(app_id=app_id, host=host, api_key=api_key, config_fname=config_fname)
250
+ tracing = Tracing(
251
+ host=singleton.host, # type: ignore
239
252
  app_id=singleton.app_id, # type: ignore
240
- variant_id=singleton.variant_id, # type: ignore
241
- variant_name=singleton.variant_name,
242
253
  api_key=singleton.api_key,
243
254
  max_workers=max_workers,
244
255
  )
256
+ set_global(setup=singleton.setup, config=singleton.config, tracing=tracing)
@@ -0,0 +1,10 @@
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