agenta 0.21.0a1__py3-none-any.whl → 0.22.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
@@ -3,7 +3,6 @@ from .sdk.context import get_contexts, save_context
3
3
  from .sdk.types import (
4
4
  Context,
5
5
  DictInput,
6
- MultipleChoice,
7
6
  FloatParam,
8
7
  InFile,
9
8
  IntParam,
@@ -23,7 +22,7 @@ from .sdk.agenta_init import Config, AgentaSingleton, init
23
22
  from .sdk.utils.helper.openai_cost import calculate_token_usage
24
23
  from .sdk.client import Agenta
25
24
  from .sdk.tracing import callbacks
26
- from .sdk.config_manager import ConfigManager
25
+
27
26
 
28
27
  config = PreInitObject("agenta.config", Config)
29
28
  DEFAULT_AGENTA_SINGLETON_INSTANCE = AgentaSingleton()
@@ -3,13 +3,12 @@ import shutil
3
3
  import tarfile
4
4
  import tempfile
5
5
  from pathlib import Path
6
- import os
7
6
 
8
7
 
9
8
  logger = logging.getLogger(__name__)
10
9
  logger.setLevel(logging.DEBUG)
11
10
 
12
- DEBUG = os.environ.get("AGENTA_CLI_DEBUG", False)
11
+ DEBUG = False
13
12
 
14
13
 
15
14
  def create_dockerfile(out_folder: Path) -> Path:
agenta/sdk/__init__.py CHANGED
@@ -3,7 +3,6 @@ from .context import get_contexts, save_context
3
3
  from .types import (
4
4
  Context,
5
5
  DictInput,
6
- MultipleChoice,
7
6
  FloatParam,
8
7
  InFile,
9
8
  IntParam,
@@ -20,7 +19,6 @@ from .decorators.tracing import instrument
20
19
  from .decorators.llm_entrypoint import entrypoint, app, route
21
20
  from .agenta_init import Config, AgentaSingleton, init
22
21
  from .utils.helper.openai_cost import calculate_token_usage
23
- from .config_manager import ConfigManager
24
22
 
25
23
  config = PreInitObject("agenta.config", Config)
26
24
  DEFAULT_AGENTA_SINGLETON_INSTANCE = AgentaSingleton()
@@ -1,6 +1,5 @@
1
1
  """The code for the Agenta SDK"""
2
2
 
3
- from agenta.sdk.utils.debug import debug, DEBUG, SHIFT
4
3
  import os
5
4
  import sys
6
5
  import time
@@ -31,7 +30,6 @@ from agenta.sdk.types import (
31
30
  InFile,
32
31
  IntParam,
33
32
  MultipleChoiceParam,
34
- MultipleChoice,
35
33
  GroupedMultipleChoiceParam,
36
34
  TextParam,
37
35
  MessagesInput,
@@ -39,16 +37,8 @@ from agenta.sdk.types import (
39
37
  BaseResponse,
40
38
  BinaryParam,
41
39
  )
42
- import pydantic
43
-
44
- from pydantic import BaseModel
45
- from typing import Type
46
- from annotated_types import Ge, Le, Gt, Lt
47
40
 
48
41
  from pydantic import BaseModel, HttpUrl
49
- import contextvars
50
- from contextlib import contextmanager
51
-
52
42
 
53
43
  app = FastAPI()
54
44
 
@@ -66,30 +56,10 @@ app.add_middleware(
66
56
 
67
57
  app.include_router(router, prefix="")
68
58
 
59
+ from agenta.sdk.utils.debug import debug, DEBUG, SHIFT
69
60
 
70
- logging.setLevel("DEBUG")
71
61
 
72
- route_context = contextvars.ContextVar("route_context", default={})
73
-
74
-
75
- @contextmanager
76
- def route_context_manager(
77
- config: Optional[Dict[str, Any]] = None,
78
- environment: Optional[str] = None,
79
- version: Optional[str] = None,
80
- variant: Optional[str] = None,
81
- ):
82
- context = {
83
- "config": config,
84
- "environment": environment,
85
- "version": version,
86
- "variant": variant,
87
- }
88
- token = route_context.set(context)
89
- try:
90
- yield
91
- finally:
92
- route_context.reset(token)
62
+ logging.setLevel("DEBUG")
93
63
 
94
64
 
95
65
  class PathValidator(BaseModel):
@@ -102,18 +72,16 @@ class route(BaseDecorator):
102
72
  # the @entrypoint decorator, which has certain limitations. By using @route(), we can create new
103
73
  # routes without altering the main workflow entrypoint. This helps in modularizing the services
104
74
  # and provides flexibility in how we expose different functionalities as APIs.
105
- def __init__(self, path, config_schema: BaseModel):
106
- self.config_schema: BaseModel = config_schema
107
- if path != "" and path[0] != "/":
108
- path = "/" + path
75
+ def __init__(self, path):
76
+ path = "/" + path.strip("/").strip()
77
+ path = "" if path == "/" else path
78
+
109
79
  PathValidator(url=f"http://example.com{path}")
110
80
 
111
81
  self.route_path = path
112
82
 
113
83
  def __call__(self, f):
114
- self.e = entrypoint(
115
- f, route_path=self.route_path, config_schema=self.config_schema
116
- )
84
+ self.e = entrypoint(f, route_path=self.route_path)
117
85
 
118
86
  return f
119
87
 
@@ -151,29 +119,15 @@ class entrypoint(BaseDecorator):
151
119
 
152
120
  routes = list()
153
121
 
154
- def __init__(
155
- self, func: Callable[..., Any], route_path="", config_schema: BaseModel = None
156
- ):
122
+ def __init__(self, func: Callable[..., Any], route_path=""):
157
123
  logging.info(f"Using Agenta Python SDK version {version('agenta')}")
158
124
 
159
125
  DEFAULT_PATH = "generate"
160
126
  PLAYGROUND_PATH = "/playground"
161
127
  RUN_PATH = "/run"
162
- func_signature = inspect.signature(func)
163
- try:
164
- config = (
165
- config_schema() if config_schema else None
166
- ) # we initialize the config object to be able to use it
167
- except pydantic.ValidationError as e:
168
- raise ValueError(
169
- f"Error initializing config_schema. Please ensure all required fields have default values: {str(e)}"
170
- ) from e
171
- except Exception as e:
172
- raise ValueError(
173
- f"Unexpected error initializing config_schema: {str(e)}"
174
- ) from e
175
128
 
176
- config_params = config.dict() if config else ag.config.all()
129
+ func_signature = inspect.signature(func)
130
+ config_params = ag.config.all()
177
131
  ingestible_files = self.extract_ingestible_files(func_signature)
178
132
 
179
133
  ### --- Playground --- #
@@ -182,44 +136,36 @@ class entrypoint(BaseDecorator):
182
136
  async def wrapper(*args, **kwargs) -> Any:
183
137
  func_params, api_config_params = self.split_kwargs(kwargs, config_params)
184
138
  self.ingest_files(func_params, ingestible_files)
185
- if not config_schema:
186
- ag.config.set(**api_config_params)
139
+ ag.config.set(**api_config_params)
187
140
 
188
141
  # Set the configuration and environment of the LLM app parent span at run-time
189
142
  ag.tracing.update_baggage(
190
143
  {"config": config_params, "environment": "playground"}
191
144
  )
192
- with route_context_manager(config=api_config_params):
193
- entrypoint_result = await self.execute_function(
194
- func,
195
- True, # inline trace: True
196
- *args,
197
- params=func_params,
198
- config_params=config_params,
199
- )
145
+
146
+ entrypoint_result = await self.execute_function(
147
+ func,
148
+ True, # inline trace: True
149
+ *args,
150
+ params=func_params,
151
+ config_params=config_params,
152
+ )
200
153
 
201
154
  return entrypoint_result
202
155
 
203
156
  self.update_function_signature(
204
- wrapper=wrapper,
205
- func_signature=func_signature,
206
- config_class=config,
207
- config_dict=config_params,
208
- ingestible_files=ingestible_files,
157
+ wrapper, func_signature, config_params, ingestible_files
209
158
  )
210
159
 
211
160
  #
212
- if route_path == "" or route_path == "/":
161
+ if route_path == "":
213
162
  route = f"/{DEFAULT_PATH}"
214
163
  app.post(route, response_model=BaseResponse)(wrapper)
215
164
  entrypoint.routes.append(
216
165
  {
217
166
  "func": func.__name__,
218
167
  "endpoint": route,
219
- "params": {**config_params, **func_signature.parameters}
220
- if not config
221
- else func_signature.parameters,
222
- "config": config,
168
+ "params": {**config_params, **func_signature.parameters},
223
169
  }
224
170
  )
225
171
 
@@ -229,10 +175,7 @@ class entrypoint(BaseDecorator):
229
175
  {
230
176
  "func": func.__name__,
231
177
  "endpoint": route,
232
- "params": {**config_params, **func_signature.parameters}
233
- if not config
234
- else func_signature.parameters,
235
- "config": config,
178
+ "params": {**config_params, **func_signature.parameters},
236
179
  }
237
180
  )
238
181
  ### ---------------------------- #
@@ -244,28 +187,26 @@ class entrypoint(BaseDecorator):
244
187
  func_params = {
245
188
  k: v for k, v in kwargs.items() if k not in ["config", "environment"]
246
189
  }
247
- if not config_schema:
248
- if "environment" in kwargs and kwargs["environment"] is not None:
249
- ag.config.pull(environment_name=kwargs["environment"])
250
- elif "config" in kwargs and kwargs["config"] is not None:
251
- ag.config.pull(config_name=kwargs["config"])
252
- else:
253
- ag.config.pull(config_name="default")
190
+
191
+ if "environment" in kwargs and kwargs["environment"] is not None:
192
+ ag.config.pull(environment_name=kwargs["environment"])
193
+ elif "config" in kwargs and kwargs["config"] is not None:
194
+ ag.config.pull(config_name=kwargs["config"])
195
+ else:
196
+ ag.config.pull(config_name="default")
254
197
 
255
198
  # Set the configuration and environment of the LLM app parent span at run-time
256
199
  ag.tracing.update_baggage(
257
200
  {"config": config_params, "environment": kwargs["environment"]}
258
201
  )
259
- with route_context_manager(
260
- variant=kwargs["config"], environment=kwargs["environment"]
261
- ):
262
- entrypoint_result = await self.execute_function(
263
- func,
264
- False, # inline trace: False
265
- *args,
266
- params=func_params,
267
- config_params=config_params,
268
- )
202
+
203
+ entrypoint_result = await self.execute_function(
204
+ func,
205
+ False, # inline trace: False
206
+ *args,
207
+ params=func_params,
208
+ config_params=config_params,
209
+ )
269
210
 
270
211
  return entrypoint_result
271
212
 
@@ -274,7 +215,8 @@ class entrypoint(BaseDecorator):
274
215
  func_signature,
275
216
  ingestible_files,
276
217
  )
277
- if route_path == "" or route_path == "/":
218
+
219
+ if route_path == "":
278
220
  route_deployed = f"/{DEFAULT_PATH}_deployed"
279
221
  app.post(route_deployed, response_model=BaseResponse)(wrapper_deployed)
280
222
 
@@ -289,18 +231,11 @@ class entrypoint(BaseDecorator):
289
231
  for route in entrypoint.routes:
290
232
  self.override_schema(
291
233
  openapi_schema=openapi_schema,
292
- func_name=route["func"],
234
+ func=route["func"],
293
235
  endpoint=route["endpoint"],
294
236
  params=route["params"],
295
237
  )
296
- if route["config"] is not None: # new SDK version
297
- self.override_config_in_schema(
298
- openapi_schema=openapi_schema,
299
- func_name=route["func"],
300
- endpoint=route["endpoint"],
301
- config=route["config"],
302
- )
303
-
238
+ ### ---------------------- #
304
239
  if self.is_main_script(func) and route_path == "":
305
240
  self.handle_terminal_run(
306
241
  func,
@@ -458,17 +393,13 @@ class entrypoint(BaseDecorator):
458
393
  self,
459
394
  wrapper: Callable[..., Any],
460
395
  func_signature: inspect.Signature,
461
- config_class: Type[BaseModel], # TODO: change to our type
462
- config_dict: Dict[str, Any],
396
+ config_params: Dict[str, Any],
463
397
  ingestible_files: Dict[str, inspect.Parameter],
464
398
  ) -> None:
465
399
  """Update the function signature to include new parameters."""
466
400
 
467
401
  updated_params: List[inspect.Parameter] = []
468
- if config_class:
469
- self.add_config_params_to_parser(updated_params, config_class)
470
- else:
471
- self.depracated_add_config_params_to_parser(updated_params, config_dict)
402
+ self.add_config_params_to_parser(updated_params, config_params)
472
403
  self.add_func_params_to_parser(updated_params, func_signature, ingestible_files)
473
404
  self.update_wrapper_signature(wrapper, updated_params)
474
405
 
@@ -488,8 +419,8 @@ class entrypoint(BaseDecorator):
488
419
  ]: # we add the config and environment parameters
489
420
  updated_params.append(
490
421
  inspect.Parameter(
491
- name=param,
492
- kind=inspect.Parameter.KEYWORD_ONLY,
422
+ param,
423
+ inspect.Parameter.KEYWORD_ONLY,
493
424
  default=Body(None),
494
425
  annotation=str,
495
426
  )
@@ -497,32 +428,17 @@ class entrypoint(BaseDecorator):
497
428
  self.update_wrapper_signature(wrapper, updated_params)
498
429
 
499
430
  def add_config_params_to_parser(
500
- self, updated_params: list, config_class: Type[BaseModel]
501
- ) -> None:
502
- """Add configuration parameters to function signature."""
503
- for name, field in config_class.__fields__.items():
504
- assert field.default is not None, f"Field {name} has no default value"
505
- updated_params.append(
506
- inspect.Parameter(
507
- name=name,
508
- kind=inspect.Parameter.KEYWORD_ONLY,
509
- annotation=field.annotation.__name__,
510
- default=Body(field.default),
511
- )
512
- )
513
-
514
- def depracated_add_config_params_to_parser(
515
- self, updated_params: list, config_dict: Dict[str, Any]
431
+ self, updated_params: list, config_params: Dict[str, Any]
516
432
  ) -> None:
517
433
  """Add configuration parameters to function signature."""
518
- for name, param in config_dict.items():
434
+ for name, param in config_params.items():
519
435
  assert (
520
436
  len(param.__class__.__bases__) == 1
521
437
  ), f"Inherited standard type of {param.__class__} needs to be one."
522
438
  updated_params.append(
523
439
  inspect.Parameter(
524
- name=name,
525
- kind=inspect.Parameter.KEYWORD_ONLY,
440
+ name,
441
+ inspect.Parameter.KEYWORD_ONLY,
526
442
  default=Body(param),
527
443
  annotation=param.__class__.__bases__[
528
444
  0
@@ -630,17 +546,10 @@ class entrypoint(BaseDecorator):
630
546
  file_path=args_func_params[name],
631
547
  )
632
548
 
633
- # Update args_config_params with default values from config_params if not provided in command line arguments
634
- args_config_params.update(
635
- {
636
- key: value
637
- for key, value in config_params.items()
638
- if key not in args_config_params
639
- }
640
- )
549
+ ag.config.set(**args_config_params)
641
550
 
642
551
  # Set the configuration and environment of the LLM app parent span at run-time
643
- ag.tracing.update_baggage({"config": args_config_params, "environment": "bash"})
552
+ ag.tracing.update_baggage({"config": ag.config.all(), "environment": "bash"})
644
553
 
645
554
  loop = asyncio.get_event_loop()
646
555
 
@@ -652,92 +561,15 @@ class entrypoint(BaseDecorator):
652
561
  )
653
562
  )
654
563
 
655
- print("\n========== Result ==========\n")
564
+ print(f"\n========== Result ==========\n")
656
565
 
657
566
  print("-> data")
658
567
  print(json.dumps(result.data, indent=2))
659
568
  print("-> trace")
660
569
  print(json.dumps(result.trace, indent=2))
661
570
 
662
- with open("trace.json", "w") as trace_file:
663
- json.dump(result.trace, trace_file, indent=4)
664
-
665
- def override_config_in_schema(
666
- self,
667
- openapi_schema: dict,
668
- func_name: str,
669
- endpoint: str,
670
- config: Type[BaseModel],
671
- ):
672
- endpoint = endpoint[1:].replace("/", "_")
673
- schema_to_override = openapi_schema["components"]["schemas"][
674
- f"Body_{func_name}_{endpoint}_post"
675
- ]["properties"]
676
- # New logic
677
- for param_name, param_val in config.__fields__.items():
678
- if param_val.annotation is str:
679
- if any(
680
- isinstance(constraint, MultipleChoice)
681
- for constraint in param_val.metadata
682
- ):
683
- choices = next(
684
- constraint.choices
685
- for constraint in param_val.metadata
686
- if isinstance(constraint, MultipleChoice)
687
- )
688
- if isinstance(choices, dict):
689
- schema_to_override[param_name]["x-parameter"] = "grouped_choice"
690
- schema_to_override[param_name]["choices"] = choices
691
- elif isinstance(choices, list):
692
- schema_to_override[param_name]["x-parameter"] = "choice"
693
- schema_to_override[param_name]["enum"] = choices
694
- else:
695
- schema_to_override[param_name]["x-parameter"] = "text"
696
- if param_val.annotation is bool:
697
- schema_to_override[param_name]["x-parameter"] = "bool"
698
- if param_val.annotation in (int, float):
699
- schema_to_override[param_name]["x-parameter"] = (
700
- "int" if param_val.annotation is int else "float"
701
- )
702
- # Check for greater than or equal to constraint
703
- if any(isinstance(constraint, Ge) for constraint in param_val.metadata):
704
- min_value = next(
705
- constraint.ge
706
- for constraint in param_val.metadata
707
- if isinstance(constraint, Ge)
708
- )
709
- schema_to_override[param_name]["minimum"] = min_value
710
- # Check for greater than constraint
711
- elif any(
712
- isinstance(constraint, Gt) for constraint in param_val.metadata
713
- ):
714
- min_value = next(
715
- constraint.gt
716
- for constraint in param_val.metadata
717
- if isinstance(constraint, Gt)
718
- )
719
- schema_to_override[param_name]["exclusiveMinimum"] = min_value
720
- # Check for less than or equal to constraint
721
- if any(isinstance(constraint, Le) for constraint in param_val.metadata):
722
- max_value = next(
723
- constraint.le
724
- for constraint in param_val.metadata
725
- if isinstance(constraint, Le)
726
- )
727
- schema_to_override[param_name]["maximum"] = max_value
728
- # Check for less than constraint
729
- elif any(
730
- isinstance(constraint, Lt) for constraint in param_val.metadata
731
- ):
732
- max_value = next(
733
- constraint.lt
734
- for constraint in param_val.metadata
735
- if isinstance(constraint, Lt)
736
- )
737
- schema_to_override[param_name]["exclusiveMaximum"] = max_value
738
-
739
571
  def override_schema(
740
- self, openapi_schema: dict, func_name: str, endpoint: str, params: dict
572
+ self, openapi_schema: dict, func: str, endpoint: str, params: dict
741
573
  ):
742
574
  """
743
575
  Overrides the default openai schema generated by fastapi with additional information about:
@@ -809,7 +641,7 @@ class entrypoint(BaseDecorator):
809
641
  endpoint = endpoint[1:].replace("/", "_")
810
642
 
811
643
  schema_to_override = openapi_schema["components"]["schemas"][
812
- f"Body_{func_name}_{endpoint}_post"
644
+ f"Body_{func}_{endpoint}_post"
813
645
  ]["properties"]
814
646
 
815
647
  for param_name, param_val in params.items():
agenta/sdk/types.py CHANGED
@@ -2,13 +2,6 @@ import json
2
2
  from typing import Dict, List, Optional, Any, Union
3
3
 
4
4
  from pydantic import ConfigDict, BaseModel, HttpUrl
5
- from dataclasses import dataclass
6
- from typing import Union
7
-
8
-
9
- @dataclass
10
- class MultipleChoice:
11
- choices: Union[List[str], Dict[str, List[str]]]
12
5
 
13
6
 
14
7
  class InFile:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: agenta
3
- Version: 0.21.0a1
3
+ Version: 0.22.0
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
@@ -27,7 +27,6 @@ Requires-Dist: pydantic (>=2)
27
27
  Requires-Dist: pymongo (>=4.6.3,<5.0.0)
28
28
  Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
29
29
  Requires-Dist: python-multipart (>=0.0.6,<0.0.10)
30
- Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
31
30
  Requires-Dist: questionary (>=1.10,<3.0)
32
31
  Requires-Dist: toml (>=0.10.2,<0.11.0)
33
32
  Project-URL: Documentation, https://docs.agenta.ai
@@ -1,4 +1,4 @@
1
- agenta/__init__.py,sha256=xTGdwyG08dOtbW_jZNMQ7fXwxeZnIIFXdYEnJfSBW8s,959
1
+ agenta/__init__.py,sha256=nL_Fogmx_64xS--WjhE4gE_0h5LIJDbDGKpjZoNJ9oI,894
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=Wz0ODhoeKK3Qg_CFUhu6D909szk05tc8ZVBB6H1-w7k,9763
@@ -125,14 +125,13 @@ agenta/docker/docker-assets/README.md,sha256=XHxwh2ks_ozrtAU7SLbL3J14SB2holG6buo
125
125
  agenta/docker/docker-assets/entrypoint.sh,sha256=29XK8VQjQsx4hN2j-4JDy-6kQb5y4LCqZEa7PD4eqCQ,74
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
- agenta/docker/docker_utils.py,sha256=kO1q2_IR0fEAo4M-2Pt_v-zC7GxxnkLogjKFhU869Ps,3555
129
- agenta/sdk/__init__.py,sha256=XyxMUm8-fCH6G6KAFU0iAfiKTGEzNzBtbAfCp9i1Y7o,831
128
+ agenta/docker/docker_utils.py,sha256=5uHMCzXkCvIsDdEiwbnnn97KkzsFbBvyMwogCsv_Z5U,3509
129
+ agenta/sdk/__init__.py,sha256=ewYNjm6AHlqkIrPfX2D_pXZMwShOdhEUcWXb7xGA2bk,769
130
130
  agenta/sdk/agenta_init.py,sha256=8MfDuypxohd0qRTdtGjX7L17KW-1UGmzNVdiqF15_ak,9790
131
131
  agenta/sdk/client.py,sha256=trKyBOYFZRk0v5Eptxvh87yPf50Y9CqY6Qgv4Fy-VH4,2142
132
- agenta/sdk/config_manager.py,sha256=D4VhCvoDe65IhMYSiNzdmcQSvc32ho9lovxpAPFHIiE,8011
133
132
  agenta/sdk/context.py,sha256=q-PxL05-I84puunUAs9LGsffEXcYhDxhQxjuOz2vK90,901
134
133
  agenta/sdk/decorators/base.py,sha256=9aNdX5h8a2mFweuhdO-BQPwXGKY9ONPIdLRhSGAGMfY,217
135
- agenta/sdk/decorators/llm_entrypoint.py,sha256=38l7S17HH09gO_t7A8Qwd2m8_Ldk8BFBknK7aKWeelU,35483
134
+ agenta/sdk/decorators/llm_entrypoint.py,sha256=9GFT6dpVWY2_1Ckh1Y_N0xSXwosoSjtNtqMEM7u55uY,28224
136
135
  agenta/sdk/decorators/tracing.py,sha256=e0olx2EEdjXY0NqpIoDJSVxCnUmv0woewTUuCJXy2tM,4166
137
136
  agenta/sdk/router.py,sha256=0sbajvn5C7t18anH6yNo7-oYxldHnYfwcbmQnIXBePw,269
138
137
  agenta/sdk/tracing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -141,7 +140,7 @@ agenta/sdk/tracing/llm_tracing.py,sha256=FfZQcID-8E4G0R34H29SA05yFUNDMEPccb4MqVc
141
140
  agenta/sdk/tracing/logger.py,sha256=GfH7V-jBHcn7h5dbdrnkDMe_ml3wkXFBeoQiqR4KVRc,474
142
141
  agenta/sdk/tracing/tasks_manager.py,sha256=FBSFOWIKBycyA4ShB2ZVMzrzYQ8pWGWWBClFX8nlZFA,3726
143
142
  agenta/sdk/tracing/tracing_context.py,sha256=nt3ewa-TK9BRJviGIZYazsAQUiG4daWxjtsbjeaDprs,789
144
- agenta/sdk/types.py,sha256=1AXUKTURFFgPH5iWeTYcNcg6dxVo1RrD0WuVe9e-NgU,5919
143
+ agenta/sdk/types.py,sha256=DSsKtoYh1ka_ketfkN10F0v8Oe2O4BB0WfnTkdIEyxE,5773
145
144
  agenta/sdk/utils/debug.py,sha256=QyuPsSoN0425UD13x_msPxSF_VT6YwHiQunZUibI-jg,2149
146
145
  agenta/sdk/utils/globals.py,sha256=JmhJcCOSbwvjQ6GDyUc2_SYR27DZk7YcrRH80ktHHOM,435
147
146
  agenta/sdk/utils/helper/openai_cost.py,sha256=1VkgvucDnNZm1pTfcVLz9icWunntp1d7zwMmnviy3Uw,5877
@@ -161,7 +160,7 @@ agenta/templates/simple_prompt/app.py,sha256=kODgF6lhzsaJPdgL5b21bUki6jkvqjWZzWR
161
160
  agenta/templates/simple_prompt/env.example,sha256=g9AE5bYcGPpxawXMJ96gh8oenEPCHTabsiOnfQo3c5k,70
162
161
  agenta/templates/simple_prompt/requirements.txt,sha256=ywRglRy7pPkw8bljmMEJJ4aOOQKrt9FGKULZ-DGkoBU,23
163
162
  agenta/templates/simple_prompt/template.toml,sha256=DQBtRrF4GU8LBEXOZ-GGuINXMQDKGTEG5y37tnvIUIE,60
164
- agenta-0.21.0a1.dist-info/METADATA,sha256=g-T2aQrTVGXMV5YNnX4nf2cKLGdyk6Dq39IBGLk3SU4,26501
165
- agenta-0.21.0a1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
166
- agenta-0.21.0a1.dist-info/entry_points.txt,sha256=PDiu8_8AsL7ibU9v4iNoOKR1S7F2rdxjlEprjM9QOgo,46
167
- agenta-0.21.0a1.dist-info/RECORD,,
163
+ agenta-0.22.0.dist-info/METADATA,sha256=61iNQilDYI86Hl2HzsyLwlAhETYPJjMHW-Rsv1SU-Lw,26460
164
+ agenta-0.22.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
165
+ agenta-0.22.0.dist-info/entry_points.txt,sha256=PDiu8_8AsL7ibU9v4iNoOKR1S7F2rdxjlEprjM9QOgo,46
166
+ agenta-0.22.0.dist-info/RECORD,,
@@ -1,205 +0,0 @@
1
- import json
2
- import logging
3
- from pathlib import Path
4
- from typing import Optional, Type, TypeVar
5
-
6
- import yaml
7
- from pydantic import BaseModel, ValidationError
8
-
9
- from agenta.client.backend.client import AgentaApi
10
- from agenta.sdk.decorators.llm_entrypoint import route_context
11
-
12
- from . import AgentaSingleton
13
-
14
- T = TypeVar("T", bound=BaseModel)
15
-
16
- logger = logging.getLogger(__name__)
17
- singleton = AgentaSingleton()
18
-
19
-
20
- class ConfigManager:
21
- client = None
22
-
23
- @staticmethod
24
- def get_from_route(schema: Type[T]) -> T:
25
- """
26
- Retrieves the configuration from the route context and returns a config object.
27
-
28
- This method checks the route context for configuration information and returns
29
- an instance of the specified schema based on the available context data.
30
-
31
- Args:
32
- schema (Type[T]): A Pydantic model class that defines the structure of the configuration.
33
-
34
- Returns:
35
- T: An instance of the specified schema populated with the configuration data.
36
-
37
- Raises:
38
- ValueError: If conflicting configuration sources are provided or if no valid
39
- configuration source is found in the context.
40
-
41
- Note:
42
- The method prioritizes the inputs in the following way:
43
- 1. 'config' (i.e. when called explicitly from the playground)
44
- 2. 'environment'
45
- 3. 'variant'
46
- Only one of these should be provided.
47
- """
48
- context = route_context.get()
49
- if ("config" in context and context["config"]) and (
50
- ("environment" in context and context["environment"])
51
- or ("variant" in context and context["variant"])
52
- ):
53
- raise ValueError(
54
- "Either config, environment or variant must be provided. Not both."
55
- )
56
- if "config" in context and context["config"]:
57
- return schema(**context["config"])
58
- elif "environment" in context and context["environment"]:
59
- return ConfigManager.get_from_backend(
60
- schema, environment=context["environment"]
61
- )
62
- elif "variant" in context and context["variant"]:
63
- return ConfigManager.get_from_backend(schema, variant=context["variant"])
64
- else:
65
- raise ValueError("Either config, environment or variant must be provided")
66
-
67
- @staticmethod
68
- def get_from_backend(
69
- schema: Type[T],
70
- environment: Optional[str] = None,
71
- version: Optional[str] = None,
72
- variant: Optional[str] = None,
73
- ) -> T:
74
- """
75
- Pulls the parameters for the app variant from the server and returns a config object.
76
-
77
- This method retrieves the configuration from the backend server based on the provided
78
- environment or variant. It then validates and returns the configuration as an instance
79
- of the specified schema.
80
-
81
- Args:
82
- schema (Type[T]): A Pydantic model class that defines the structure of the configuration.
83
- environment (Optional[str]): The environment name to fetch the configuration for.
84
- Must be one of "development", "production", or "staging".
85
- version (Optional[str]): Currently not implemented. Will raise NotImplementedError if provided.
86
- variant (Optional[str]): The variant name to fetch the configuration for.
87
-
88
- Returns:
89
- T: An instance of the specified schema populated with the configuration data.
90
-
91
- Raises:
92
- ValueError: If neither environment nor variant is provided.
93
- NotImplementedError: If a specific version is requested (not yet implemented).
94
- ValidationError: If the retrieved configuration data doesn't match the schema.
95
- Exception: For any other errors during the process (e.g., API communication issues).
96
-
97
- Note:
98
- Either environment or variant must be provided, but not both.
99
- """
100
- if not ConfigManager.client:
101
- try:
102
- ConfigManager.client = AgentaApi(
103
- base_url=singleton.host + "/api",
104
- api_key=singleton.api_key if singleton.api_key else "",
105
- )
106
- except Exception as ex:
107
- logger.error(
108
- "Failed to initialize Agenta client with error: %s", str(ex)
109
- )
110
- raise
111
- if not environment and not variant:
112
- raise ValueError("Either environment or variant must be provided")
113
- try:
114
- if environment:
115
- if version:
116
- raise NotImplementedError(
117
- "Getting config for a specific version is not implemented yet."
118
- )
119
- else:
120
- assert environment in [
121
- "development",
122
- "production",
123
- "staging",
124
- ], "Environment must be either development, production or staging"
125
- config = ConfigManager.client.configs.get_config(
126
- base_id=singleton.base_id, environment_name=environment
127
- )
128
- elif variant:
129
- config = ConfigManager.client.configs.get_config(
130
- base_id=singleton.base_id, config_name=variant
131
- )
132
- except Exception as ex:
133
- logger.error(
134
- "Failed to pull the configuration from the server with error: %s",
135
- str(ex),
136
- )
137
-
138
- try:
139
- result = schema(**config.parameters)
140
- except ValidationError as ex:
141
- logger.error("Failed to validate the configuration with error: %s", str(ex))
142
- raise
143
- return result
144
-
145
- @staticmethod
146
- def get_from_yaml(filename: str, schema: Type[T]) -> T:
147
- """
148
- Loads configuration from a YAML file and returns a config object.
149
-
150
- Args:
151
- filename (str): The name of the YAML file to load.
152
- schema (Type[T]): A Pydantic model class that defines the structure of the configuration.
153
-
154
- Returns:
155
- T: An instance of the specified schema populated with the configuration data.
156
-
157
- Raises:
158
- FileNotFoundError: If the specified file doesn't exist.
159
- ValidationError: If the loaded configuration data doesn't match the schema.
160
- """
161
- file_path = Path(filename)
162
- if not file_path.exists():
163
- raise FileNotFoundError(f"Config file not found: {filename}")
164
-
165
- with open(file_path, "r") as file:
166
- config_data = yaml.safe_load(file)
167
-
168
- try:
169
- return schema(**config_data)
170
- except ValidationError as ex:
171
- logger.error(
172
- f"Failed to validate the configuration from {filename} with error: {str(ex)}"
173
- )
174
- raise
175
-
176
- @staticmethod
177
- def get_from_json(filename: str, schema: Type[T]) -> T:
178
- """
179
- Loads configuration from a JSON file and returns a config object.
180
-
181
- Args:
182
- filename (str): The name of the JSON file to load.
183
- schema (Type[T]): A Pydantic model class that defines the structure of the configuration.
184
-
185
- Returns:
186
- T: An instance of the specified schema populated with the configuration data.
187
-
188
- Raises:
189
- FileNotFoundError: If the specified file doesn't exist.
190
- ValidationError: If the loaded configuration data doesn't match the schema.
191
- """
192
- file_path = Path(filename)
193
- if not file_path.exists():
194
- raise FileNotFoundError(f"Config file not found: {filename}")
195
-
196
- with open(file_path, "r") as file:
197
- config_data = json.load(file)
198
-
199
- try:
200
- return schema(**config_data)
201
- except ValidationError as ex:
202
- logger.error(
203
- f"Failed to validate the configuration from {filename} with error: {str(ex)}"
204
- )
205
- raise