agenta 0.12.2__py3-none-any.whl → 0.32.0a1__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.

Files changed (244) hide show
  1. agenta/__init__.py +64 -7
  2. agenta/cli/helper.py +7 -3
  3. agenta/cli/main.py +15 -50
  4. agenta/cli/variant_commands.py +50 -29
  5. agenta/client/Readme.md +72 -64
  6. agenta/client/api.py +2 -2
  7. agenta/client/backend/__init__.py +193 -22
  8. agenta/client/backend/access_control/__init__.py +1 -0
  9. agenta/client/backend/access_control/client.py +167 -0
  10. agenta/client/backend/apps/__init__.py +1 -0
  11. agenta/client/backend/apps/client.py +1691 -0
  12. agenta/client/backend/bases/__init__.py +1 -0
  13. agenta/client/backend/bases/client.py +190 -0
  14. agenta/client/backend/client.py +2508 -5712
  15. agenta/client/backend/configs/__init__.py +1 -0
  16. agenta/client/backend/configs/client.py +604 -0
  17. agenta/client/backend/containers/__init__.py +5 -0
  18. agenta/client/backend/containers/client.py +648 -0
  19. agenta/client/backend/containers/types/__init__.py +5 -0
  20. agenta/client/backend/{types → containers/types}/container_templates_response.py +1 -2
  21. agenta/client/backend/core/__init__.py +30 -0
  22. agenta/client/backend/core/client_wrapper.py +42 -9
  23. agenta/client/backend/core/file.py +70 -0
  24. agenta/client/backend/core/http_client.py +575 -0
  25. agenta/client/backend/core/jsonable_encoder.py +33 -39
  26. agenta/client/backend/core/pydantic_utilities.py +325 -0
  27. agenta/client/backend/core/query_encoder.py +60 -0
  28. agenta/client/backend/core/remove_none_from_dict.py +2 -2
  29. agenta/client/backend/core/request_options.py +35 -0
  30. agenta/client/backend/core/serialization.py +276 -0
  31. agenta/client/backend/environments/__init__.py +1 -0
  32. agenta/client/backend/environments/client.py +196 -0
  33. agenta/client/backend/evaluations/__init__.py +1 -0
  34. agenta/client/backend/evaluations/client.py +1469 -0
  35. agenta/client/backend/evaluators/__init__.py +1 -0
  36. agenta/client/backend/evaluators/client.py +1283 -0
  37. agenta/client/backend/observability/__init__.py +1 -0
  38. agenta/client/backend/observability/client.py +1286 -0
  39. agenta/client/backend/observability_v_1/__init__.py +5 -0
  40. agenta/client/backend/observability_v_1/client.py +763 -0
  41. agenta/client/backend/observability_v_1/types/__init__.py +7 -0
  42. agenta/client/backend/observability_v_1/types/format.py +5 -0
  43. agenta/client/backend/observability_v_1/types/query_analytics_response.py +7 -0
  44. agenta/client/backend/observability_v_1/types/query_traces_response.py +11 -0
  45. agenta/client/backend/scopes/__init__.py +1 -0
  46. agenta/client/backend/scopes/client.py +114 -0
  47. agenta/client/backend/testsets/__init__.py +1 -0
  48. agenta/client/backend/testsets/client.py +1284 -0
  49. agenta/client/backend/types/__init__.py +154 -26
  50. agenta/client/backend/types/agenta_node_dto.py +48 -0
  51. agenta/client/backend/types/agenta_node_dto_nodes_value.py +6 -0
  52. agenta/client/backend/types/agenta_nodes_response.py +30 -0
  53. agenta/client/backend/types/agenta_root_dto.py +30 -0
  54. agenta/client/backend/types/agenta_roots_response.py +30 -0
  55. agenta/client/backend/types/agenta_tree_dto.py +30 -0
  56. agenta/client/backend/types/agenta_trees_response.py +30 -0
  57. agenta/client/backend/types/aggregated_result.py +16 -31
  58. agenta/client/backend/types/aggregated_result_evaluator_config.py +8 -0
  59. agenta/client/backend/types/analytics_response.py +24 -0
  60. agenta/client/backend/types/app.py +17 -30
  61. agenta/client/backend/types/app_variant_response.py +36 -0
  62. agenta/client/backend/types/app_variant_revision.py +17 -32
  63. agenta/client/backend/types/base_output.py +13 -28
  64. agenta/client/backend/types/body_import_testset.py +15 -31
  65. agenta/client/backend/types/bucket_dto.py +26 -0
  66. agenta/client/backend/types/collect_status_response.py +22 -0
  67. agenta/client/backend/types/config_db.py +16 -31
  68. agenta/client/backend/types/config_dto.py +32 -0
  69. agenta/client/backend/types/config_response_model.py +32 -0
  70. agenta/client/backend/types/correct_answer.py +22 -0
  71. agenta/client/backend/types/create_app_output.py +13 -28
  72. agenta/client/backend/types/create_span.py +45 -0
  73. agenta/client/backend/types/create_trace_response.py +22 -0
  74. agenta/client/backend/types/docker_env_vars.py +13 -28
  75. agenta/client/backend/types/environment_output.py +22 -34
  76. agenta/client/backend/types/environment_output_extended.py +31 -0
  77. agenta/client/backend/types/environment_revision.py +26 -0
  78. agenta/client/backend/types/error.py +22 -0
  79. agenta/client/backend/types/evaluation.py +22 -33
  80. agenta/client/backend/types/evaluation_scenario.py +18 -33
  81. agenta/client/backend/types/evaluation_scenario_input.py +16 -31
  82. agenta/client/backend/types/evaluation_scenario_output.py +17 -30
  83. agenta/client/backend/types/evaluation_scenario_result.py +14 -29
  84. agenta/client/backend/types/evaluation_scenario_score_update.py +21 -0
  85. agenta/client/backend/types/evaluation_status_enum.py +11 -29
  86. agenta/client/backend/types/evaluation_type.py +3 -21
  87. agenta/client/backend/types/evaluator.py +20 -31
  88. agenta/client/backend/types/evaluator_config.py +21 -33
  89. agenta/client/backend/types/evaluator_mapping_output_interface.py +21 -0
  90. agenta/client/backend/types/evaluator_output_interface.py +21 -0
  91. agenta/client/backend/types/exception_dto.py +26 -0
  92. agenta/client/backend/types/get_config_response.py +23 -0
  93. agenta/client/backend/types/header_dto.py +22 -0
  94. agenta/client/backend/types/http_validation_error.py +14 -29
  95. agenta/client/backend/types/human_evaluation.py +18 -34
  96. agenta/client/backend/types/human_evaluation_scenario.py +22 -38
  97. agenta/client/backend/types/human_evaluation_scenario_input.py +13 -28
  98. agenta/client/backend/types/human_evaluation_scenario_output.py +13 -28
  99. agenta/client/backend/types/human_evaluation_scenario_update.py +30 -0
  100. agenta/client/backend/types/human_evaluation_update.py +22 -0
  101. agenta/client/backend/types/image.py +18 -32
  102. agenta/client/backend/types/invite_request.py +16 -30
  103. agenta/client/backend/types/legacy_analytics_response.py +29 -0
  104. agenta/client/backend/types/legacy_data_point.py +27 -0
  105. agenta/client/backend/types/lifecycle_dto.py +24 -0
  106. agenta/client/backend/types/link_dto.py +24 -0
  107. agenta/client/backend/types/list_api_keys_response.py +24 -0
  108. agenta/client/backend/types/llm_run_rate_limit.py +13 -28
  109. agenta/client/backend/types/llm_tokens.py +23 -0
  110. agenta/client/backend/types/metrics_dto.py +24 -0
  111. agenta/client/backend/types/new_human_evaluation.py +27 -0
  112. agenta/client/backend/types/new_testset.py +16 -31
  113. agenta/client/backend/types/node_dto.py +24 -0
  114. agenta/client/backend/types/node_type.py +19 -0
  115. agenta/client/backend/types/o_tel_context_dto.py +22 -0
  116. agenta/client/backend/types/o_tel_event_dto.py +23 -0
  117. agenta/client/backend/types/o_tel_extra_dto.py +26 -0
  118. agenta/client/backend/types/o_tel_link_dto.py +23 -0
  119. agenta/client/backend/types/o_tel_span_dto.py +37 -0
  120. agenta/client/backend/types/o_tel_span_kind.py +15 -0
  121. agenta/client/backend/types/o_tel_spans_response.py +24 -0
  122. agenta/client/backend/types/o_tel_status_code.py +8 -0
  123. agenta/client/backend/types/organization.py +22 -35
  124. agenta/client/backend/types/organization_output.py +13 -28
  125. agenta/client/backend/types/outputs.py +5 -0
  126. agenta/client/backend/types/parent_dto.py +21 -0
  127. agenta/client/backend/types/permission.py +41 -0
  128. agenta/client/backend/types/projects_response.py +28 -0
  129. agenta/client/backend/types/provider_key_dto.py +23 -0
  130. agenta/client/backend/types/provider_kind.py +21 -0
  131. agenta/client/backend/types/reference_dto.py +23 -0
  132. agenta/client/backend/types/reference_request_model.py +23 -0
  133. agenta/client/backend/types/result.py +18 -31
  134. agenta/client/backend/types/root_dto.py +21 -0
  135. agenta/client/backend/types/{human_evaluation_scenario_score.py → score.py} +1 -1
  136. agenta/client/backend/types/secret_dto.py +24 -0
  137. agenta/client/backend/types/{human_evaluation_scenario_update_score.py → secret_kind.py} +1 -1
  138. agenta/client/backend/types/secret_response_dto.py +27 -0
  139. agenta/client/backend/types/simple_evaluation_output.py +13 -28
  140. agenta/client/backend/types/span.py +39 -49
  141. agenta/client/backend/types/span_detail.py +44 -0
  142. agenta/client/backend/types/span_dto.py +54 -0
  143. agenta/client/backend/types/span_dto_nodes_value.py +9 -0
  144. agenta/client/backend/types/span_status_code.py +5 -0
  145. agenta/client/backend/types/span_variant.py +23 -0
  146. agenta/client/backend/types/status_code.py +5 -0
  147. agenta/client/backend/types/status_dto.py +23 -0
  148. agenta/client/backend/types/template.py +14 -29
  149. agenta/client/backend/types/template_image_info.py +21 -35
  150. agenta/client/backend/types/test_set_output_response.py +20 -33
  151. agenta/client/backend/types/test_set_simple_response.py +13 -28
  152. agenta/client/backend/types/time_dto.py +23 -0
  153. agenta/client/backend/types/trace_detail.py +44 -0
  154. agenta/client/backend/types/tree_dto.py +23 -0
  155. agenta/client/backend/types/tree_type.py +5 -0
  156. agenta/client/backend/types/update_app_output.py +22 -0
  157. agenta/client/backend/types/uri.py +13 -28
  158. agenta/client/backend/types/validation_error.py +13 -28
  159. agenta/client/backend/types/variant_action.py +14 -29
  160. agenta/client/backend/types/variant_action_enum.py +1 -19
  161. agenta/client/backend/types/with_pagination.py +26 -0
  162. agenta/client/backend/types/workspace_member_response.py +23 -0
  163. agenta/client/backend/types/workspace_permission.py +25 -0
  164. agenta/client/backend/types/workspace_response.py +29 -0
  165. agenta/client/backend/types/workspace_role.py +15 -0
  166. agenta/client/backend/types/workspace_role_response.py +23 -0
  167. agenta/client/backend/variants/__init__.py +5 -0
  168. agenta/client/backend/variants/client.py +2814 -0
  169. agenta/client/backend/variants/types/__init__.py +7 -0
  170. agenta/client/backend/variants/types/add_variant_from_base_and_config_response.py +8 -0
  171. agenta/client/backend/vault/__init__.py +1 -0
  172. agenta/client/backend/vault/client.py +685 -0
  173. agenta/client/client.py +1 -1
  174. agenta/config.py +0 -2
  175. agenta/config.toml +0 -1
  176. agenta/docker/docker-assets/Dockerfile.cloud.template +2 -1
  177. agenta/docker/docker-assets/Dockerfile.template +2 -1
  178. agenta/docker/docker_utils.py +11 -12
  179. agenta/sdk/__init__.py +58 -7
  180. agenta/sdk/agenta_init.py +182 -164
  181. agenta/sdk/assets.py +95 -0
  182. agenta/sdk/client.py +56 -0
  183. agenta/sdk/context/__init__.py +0 -0
  184. agenta/sdk/context/exporting.py +25 -0
  185. agenta/sdk/context/routing.py +27 -0
  186. agenta/sdk/context/tracing.py +28 -0
  187. agenta/sdk/decorators/__init__.py +0 -0
  188. agenta/sdk/decorators/routing.py +576 -0
  189. agenta/sdk/decorators/tracing.py +296 -0
  190. agenta/sdk/litellm/__init__.py +1 -0
  191. agenta/sdk/litellm/litellm.py +314 -0
  192. agenta/sdk/litellm/mockllm.py +27 -0
  193. agenta/sdk/litellm/mocks/__init__.py +26 -0
  194. agenta/sdk/managers/__init__.py +6 -0
  195. agenta/sdk/managers/config.py +208 -0
  196. agenta/sdk/managers/deployment.py +45 -0
  197. agenta/sdk/managers/secrets.py +38 -0
  198. agenta/sdk/managers/shared.py +639 -0
  199. agenta/sdk/managers/variant.py +182 -0
  200. agenta/sdk/managers/vault.py +16 -0
  201. agenta/sdk/middleware/__init__.py +0 -0
  202. agenta/sdk/middleware/auth.py +180 -0
  203. agenta/sdk/middleware/cache.py +47 -0
  204. agenta/sdk/middleware/config.py +255 -0
  205. agenta/sdk/middleware/cors.py +29 -0
  206. agenta/sdk/middleware/inline.py +38 -0
  207. agenta/sdk/middleware/mock.py +33 -0
  208. agenta/sdk/middleware/otel.py +40 -0
  209. agenta/sdk/middleware/vault.py +145 -0
  210. agenta/sdk/router.py +0 -7
  211. agenta/sdk/tracing/__init__.py +1 -0
  212. agenta/sdk/tracing/attributes.py +141 -0
  213. agenta/sdk/tracing/conventions.py +49 -0
  214. agenta/sdk/tracing/exporters.py +103 -0
  215. agenta/sdk/tracing/inline.py +1146 -0
  216. agenta/sdk/tracing/processors.py +121 -0
  217. agenta/sdk/tracing/spans.py +136 -0
  218. agenta/sdk/tracing/tracing.py +237 -0
  219. agenta/sdk/types.py +478 -74
  220. agenta/sdk/utils/__init__.py +0 -0
  221. agenta/sdk/utils/constants.py +1 -0
  222. agenta/sdk/utils/{helper/openai_cost.py → costs.py} +3 -0
  223. agenta/sdk/utils/exceptions.py +59 -0
  224. agenta/sdk/utils/globals.py +6 -10
  225. agenta/sdk/utils/helpers.py +8 -0
  226. agenta/sdk/utils/logging.py +21 -0
  227. agenta/sdk/utils/singleton.py +13 -0
  228. agenta/sdk/utils/timing.py +58 -0
  229. {agenta-0.12.2.dist-info → agenta-0.32.0a1.dist-info}/METADATA +98 -151
  230. agenta-0.32.0a1.dist-info/RECORD +263 -0
  231. {agenta-0.12.2.dist-info → agenta-0.32.0a1.dist-info}/WHEEL +1 -1
  232. agenta/client/backend/types/add_variant_from_base_and_config_response.py +0 -7
  233. agenta/client/backend/types/app_variant_output.py +0 -47
  234. agenta/client/backend/types/app_variant_output_extended.py +0 -50
  235. agenta/client/backend/types/delete_evaluation.py +0 -36
  236. agenta/client/backend/types/evaluation_webhook.py +0 -36
  237. agenta/client/backend/types/feedback.py +0 -40
  238. agenta/client/backend/types/get_config_reponse.py +0 -39
  239. agenta/client/backend/types/list_api_keys_output.py +0 -39
  240. agenta/client/backend/types/trace.py +0 -48
  241. agenta/sdk/agenta_decorator.py +0 -443
  242. agenta/sdk/context.py +0 -41
  243. agenta-0.12.2.dist-info/RECORD +0 -114
  244. {agenta-0.12.2.dist-info → agenta-0.32.0a1.dist-info}/entry_points.txt +0 -0
agenta/__init__.py CHANGED
@@ -1,19 +1,76 @@
1
- from .sdk.agenta_decorator import app, entrypoint
2
- from .sdk.context import get_contexts, save_context
1
+ from typing import Any, Callable, Optional
2
+
3
+ from .sdk.utils.preinit import PreInitObject
4
+
5
+ import agenta.client.backend.types as client_types # pylint: disable=wrong-import-order
6
+
3
7
  from .sdk.types import (
4
- Context,
8
+ MCField,
5
9
  DictInput,
10
+ MultipleChoice,
6
11
  FloatParam,
7
- InFile,
8
12
  IntParam,
9
13
  MultipleChoiceParam,
14
+ GroupedMultipleChoiceParam,
10
15
  MessagesInput,
11
16
  TextParam,
12
17
  FileInputURL,
13
18
  BinaryParam,
19
+ Prompt,
20
+ PromptTemplate,
14
21
  )
15
- from .sdk.utils.preinit import PreInitObject
16
- from .sdk.agenta_init import Config, init
17
- from .sdk.utils.helper.openai_cost import calculate_token_usage
22
+
23
+ from .sdk.utils.logging import log as logging
24
+ from .sdk.tracing import Tracing, get_tracer
25
+ from .sdk.decorators.tracing import instrument
26
+ from .sdk.tracing.conventions import Reference
27
+ from .sdk.decorators.routing import entrypoint, app, route
28
+ from .sdk.agenta_init import Config, AgentaSingleton, init as _init
29
+ from .sdk.utils.costs import calculate_token_usage
30
+ from .sdk.client import Agenta
31
+ from .sdk.litellm import litellm as callbacks
32
+ from .sdk.managers.vault import VaultManager
33
+ from .sdk.managers.secrets import SecretsManager
34
+ from .sdk.managers.config import ConfigManager
35
+ from .sdk.managers.variant import VariantManager
36
+ from .sdk.managers.deployment import DeploymentManager
37
+ from .sdk import assets as assets
38
+ from .sdk import tracer
18
39
 
19
40
  config = PreInitObject("agenta.config", Config)
41
+ DEFAULT_AGENTA_SINGLETON_INSTANCE = AgentaSingleton()
42
+
43
+ types = client_types
44
+
45
+ api = None
46
+ async_api = None
47
+
48
+ tracing = DEFAULT_AGENTA_SINGLETON_INSTANCE.tracing # type: ignore
49
+ tracer = get_tracer(tracing)
50
+
51
+
52
+ def init(
53
+ host: Optional[str] = None,
54
+ api_key: Optional[str] = None,
55
+ config_fname: Optional[str] = None,
56
+ redact: Optional[Callable[..., Any]] = None,
57
+ redact_on_error: Optional[bool] = True,
58
+ # DEPRECATING
59
+ app_id: Optional[str] = None,
60
+ ):
61
+ global api, async_api, tracing, tracer # pylint: disable=global-statement
62
+
63
+ _init(
64
+ host=host,
65
+ api_key=api_key,
66
+ config_fname=config_fname,
67
+ redact=redact,
68
+ redact_on_error=redact_on_error,
69
+ app_id=app_id,
70
+ )
71
+
72
+ api = DEFAULT_AGENTA_SINGLETON_INSTANCE.api # type: ignore
73
+ async_api = DEFAULT_AGENTA_SINGLETON_INSTANCE.async_api # type: ignore
74
+
75
+ tracing = DEFAULT_AGENTA_SINGLETON_INSTANCE.tracing # type: ignore
76
+ tracer = get_tracer(tracing)
agenta/cli/helper.py CHANGED
@@ -15,6 +15,9 @@ import toml
15
15
  from agenta.client.backend.client import AgentaApi
16
16
 
17
17
  BACKEND_URL_SUFFIX = os.environ.get("BACKEND_URL_SUFFIX", "api")
18
+ POSTHOG_KEY = os.environ.get(
19
+ "POSTHOG_KEY", "phc_hmVSxIjTW1REBHXgj2aw4HW9X6CXb6FzerBgP9XenC7"
20
+ )
18
21
 
19
22
 
20
23
  def get_global_config(var_name: str) -> Optional[Any]:
@@ -97,7 +100,7 @@ def get_api_key(backend_host: str) -> str:
97
100
  ).ask()
98
101
 
99
102
  if api_key:
100
- set_global_config("api_key", api_key)
103
+ set_global_config("api_key", api_key.strip())
101
104
 
102
105
  return api_key
103
106
  elif api_key is None: # User pressed Ctrl+C
@@ -111,7 +114,8 @@ def init_telemetry_config() -> None:
111
114
  ):
112
115
  set_global_config("telemetry_tracking_enabled", True)
113
116
  set_global_config(
114
- "telemetry_api_key", "phc_hmVSxIjTW1REBHXgj2aw4HW9X6CXb6FzerBgP9XenC7"
117
+ "telemetry_api_key",
118
+ POSTHOG_KEY,
115
119
  )
116
120
 
117
121
 
@@ -137,7 +141,7 @@ def update_variants_from_backend(
137
141
  )
138
142
 
139
143
  try:
140
- variants: List[AppVariant] = client.list_app_variants(app_id=app_id)
144
+ variants: List[AppVariant] = client.apps.list_app_variants(app_id=app_id)
141
145
  except Exception as ex:
142
146
  raise ex
143
147
 
agenta/cli/main.py CHANGED
@@ -47,9 +47,9 @@ def check_latest_version() -> Union[str, None]:
47
47
 
48
48
 
49
49
  def notify_update(available_version: str):
50
- import pkg_resources
50
+ import importlib.metadata
51
51
 
52
- installed_version = pkg_resources.get_distribution("agenta").version
52
+ installed_version = importlib.metadata.version("agenta")
53
53
  if available_version > installed_version:
54
54
  click.echo(
55
55
  click.style(
@@ -78,11 +78,15 @@ def cli():
78
78
 
79
79
 
80
80
  @click.command()
81
- @click.option("--app_name", default="")
82
- @click.option("--backend_host", default="")
81
+ @click.option("--app-name", "--app_name", default=None)
82
+ @click.option("--backend-host", "backend_host", default=None)
83
83
  def init(app_name: str, backend_host: str):
84
- init_option = "Blank App" if backend_host != "" and app_name != "" else ""
85
84
  """Initialize a new Agenta app with the template files."""
85
+
86
+ init_option = "Blank App" if backend_host != "" and app_name != "" else ""
87
+
88
+ api_key = os.getenv("AGENTA_API_KEY")
89
+
86
90
  if not app_name:
87
91
  while True:
88
92
  app_name = questionary.text("Please enter the app name").ask()
@@ -125,7 +129,8 @@ def init(app_name: str, backend_host: str):
125
129
  else:
126
130
  backend_host = "https://cloud.agenta.ai"
127
131
 
128
- api_key = helper.get_api_key(backend_host)
132
+ if not api_key:
133
+ api_key = helper.get_api_key(backend_host)
129
134
 
130
135
  elif where_question is None: # User pressed Ctrl+C
131
136
  sys.exit(0)
@@ -141,50 +146,9 @@ def init(app_name: str, backend_host: str):
141
146
  api_key=api_key if where_question == "On agenta cloud" else "",
142
147
  )
143
148
 
144
- # list of user organizations
145
- user_organizations = []
146
-
147
- # validate the api key if it is provided
148
- if where_question == "On agenta cloud":
149
- try:
150
- key_prefix = api_key.split(".")[0]
151
- client.validate_api_key(key_prefix=key_prefix)
152
-
153
- # Make request to fetch user organizations after api key validation
154
- organizations = client.list_organizations()
155
- if len(organizations) >= 1:
156
- user_organizations = organizations
157
- except Exception as ex:
158
- if ex.status_code == 401:
159
- click.echo(click.style("Error: Invalid API key", fg="red"))
160
- sys.exit(1)
161
- else:
162
- click.echo(click.style(f"Error: {ex}", fg="red"))
163
- sys.exit(1)
164
-
165
- filtered_org = None
166
- if where_question == "On agenta cloud":
167
- which_organization = questionary.select(
168
- "Which organization do you want to create the app for?",
169
- choices=[
170
- f"{org.name}: {org.description}" for org in user_organizations
171
- ],
172
- ).ask()
173
- filtered_org = next(
174
- (
175
- org
176
- for org in user_organizations
177
- if org.name == which_organization.split(":")[0]
178
- ),
179
- None,
180
- )
181
-
182
149
  # Get app_id after creating new app in the backend server
183
150
  try:
184
- app_id = client.create_app(
185
- app_name=app_name,
186
- organization_id=filtered_org.id if filtered_org else None,
187
- ).app_id
151
+ app_id = client.apps.create_app(app_name=app_name).app_id
188
152
  except Exception as ex:
189
153
  click.echo(click.style(f"Error: {ex}", fg="red"))
190
154
  sys.exit(1)
@@ -241,8 +205,9 @@ def init(app_name: str, backend_host: str):
241
205
  gitignore_content = (
242
206
  "# Environments \nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\nmyenv/\n"
243
207
  )
244
- with open(".gitignore", "w") as gitignore_file:
245
- gitignore_file.write(gitignore_content)
208
+ if not os.path.exists(".agentaignore"):
209
+ with open(".agentaignore", "w") as gitignore_file:
210
+ gitignore_file.write(gitignore_content)
246
211
 
247
212
  click.echo("App initialized successfully")
248
213
  if init_option == "Start from template":
@@ -9,13 +9,15 @@ from requests.exceptions import ConnectionError
9
9
  import click
10
10
  import questionary
11
11
  import toml
12
+
12
13
  from agenta.cli import helper
13
14
  from agenta.cli.telemetry import event_track
15
+ from agenta.client.backend.client import AgentaApi
16
+ from agenta.client.api import add_variant_to_server
14
17
  from agenta.client.api_models import AppVariant, Image
15
18
  from agenta.docker.docker_utils import build_tar_docker_container
19
+ from agenta.client.backend.types.variant_action import VariantAction
16
20
 
17
- from agenta.client.api import add_variant_to_server
18
- from agenta.client.backend.client import AgentaApi
19
21
 
20
22
  BACKEND_URL_SUFFIX = os.environ.get("BACKEND_URL_SUFFIX", "api")
21
23
 
@@ -27,7 +29,7 @@ def variant():
27
29
 
28
30
 
29
31
  def add_variant(
30
- app_folder: str, file_name: str, host: str, config_name="default"
32
+ app_folder: str, file_name: str, host: str, overwrite: bool, config_name="default"
31
33
  ) -> str:
32
34
  """
33
35
  Adds a variant to the backend. Sends the code as a tar to the backend, which then containerizes it and adds it to the backend store.
@@ -95,20 +97,20 @@ def add_variant(
95
97
 
96
98
  # update the config file with the variant names from the backend
97
99
  variant_name = f"{base_name}.{config_name}"
98
- overwrite = False
99
100
 
100
101
  client = AgentaApi(
101
102
  base_url=f"{host}/{BACKEND_URL_SUFFIX}",
102
103
  api_key=api_key,
103
104
  )
104
105
 
105
- if variant_name in config["variants"]:
106
- overwrite = questionary.confirm(
107
- "This variant already exists. Do you want to overwrite it?"
108
- ).ask()
106
+ if variant_name in config["variants"] and not overwrite:
109
107
  if not overwrite:
110
- click.echo("Operation cancelled.")
111
- sys.exit(0)
108
+ overwrite = questionary.confirm(
109
+ "This variant already exists. Do you want to overwrite it?"
110
+ ).ask()
111
+ if not overwrite:
112
+ click.echo("Operation cancelled.")
113
+ return
112
114
 
113
115
  try:
114
116
  click.echo(
@@ -126,7 +128,7 @@ def add_variant(
126
128
  )
127
129
  )
128
130
  with tar_path.open("rb") as tar_file:
129
- built_image: Image = client.build_image(
131
+ built_image: Image = client.containers.build_image(
130
132
  app_id=app_id,
131
133
  base_name=base_name,
132
134
  tar_file=tar_file,
@@ -137,7 +139,7 @@ def add_variant(
137
139
 
138
140
  except Exception as ex:
139
141
  click.echo(click.style(f"Error while building image: {ex}", fg="red"))
140
- return None
142
+ raise
141
143
  try:
142
144
  if overwrite:
143
145
  click.echo(
@@ -147,14 +149,20 @@ def add_variant(
147
149
  )
148
150
  )
149
151
  variant_id = config["variant_ids"][config["variants"].index(variant_name)]
150
- client.update_variant_image(
152
+ client.variants.update_variant_image(
151
153
  variant_id=variant_id,
152
- request=image, # because Fern code uses "request: Image" instead of "image: Image"
154
+ docker_id=image.docker_id,
155
+ tags=image.tags,
156
+ type=image.type,
153
157
  ) # this automatically restarts
154
158
  else:
155
159
  click.echo(click.style(f"Adding {variant_name} to server...", fg="yellow"))
156
160
  response = add_variant_to_server(
157
- app_id, base_name, image, f"{host}/{BACKEND_URL_SUFFIX}", api_key
161
+ app_id,
162
+ base_name,
163
+ image,
164
+ f"{host}/{BACKEND_URL_SUFFIX}",
165
+ api_key,
158
166
  )
159
167
  variant_id = response["variant_id"]
160
168
  config["variants"].append(variant_name)
@@ -164,7 +172,7 @@ def add_variant(
164
172
  click.echo(click.style(f"Error while updating variant: {ex}", fg="red"))
165
173
  else:
166
174
  click.echo(click.style(f"Error while adding variant: {ex}", fg="red"))
167
- return None
175
+ raise
168
176
 
169
177
  agenta_dir = Path.home() / ".agenta"
170
178
  global_toml_file = toml.load(agenta_dir / "config.toml")
@@ -172,7 +180,7 @@ def add_variant(
172
180
  if overwrite:
173
181
  # Track a deployment event
174
182
  if tracking_enabled:
175
- get_user_id = client.user_profile()
183
+ get_user_id = client.fetch_user_profile()
176
184
  user_id = get_user_id["id"]
177
185
  event_track.capture_event(
178
186
  "app_deployment",
@@ -194,7 +202,7 @@ def add_variant(
194
202
  else:
195
203
  # Track a deployment event
196
204
  if tracking_enabled:
197
- get_user_id = client.user_profile()
205
+ get_user_id = client.fetch_user_profile()
198
206
  user_id = get_user_id["id"]
199
207
  event_track.capture_event(
200
208
  "app_deployment",
@@ -259,7 +267,11 @@ def start_variant(variant_id: str, app_folder: str, host: str):
259
267
  api_key=api_key,
260
268
  )
261
269
 
262
- endpoint = client.start_variant(variant_id=variant_id, action={"action": "START"})
270
+ variant = client.variants.start_variant(
271
+ variant_id=variant_id,
272
+ action=VariantAction(action="START"),
273
+ )
274
+ endpoint = variant.uri
263
275
  click.echo("\n" + click.style("Congratulations! 🎉", bold=True, fg="green"))
264
276
  click.echo(
265
277
  click.style("Your app has been deployed locally as an API. 🚀", fg="cyan")
@@ -327,7 +339,7 @@ def remove_variant(variant_name: str, app_folder: str, host: str):
327
339
  )
328
340
 
329
341
  try:
330
- client.remove_variant(variant_id=variant_id)
342
+ client.variants.remove_variant(variant_id=variant_id)
331
343
  except Exception as ex:
332
344
  click.echo(
333
345
  click.style(
@@ -365,7 +377,7 @@ def list_variants(app_folder: str, host: str):
365
377
  )
366
378
 
367
379
  try:
368
- variants: List[AppVariant] = client.list_app_variants(app_id=app_id)
380
+ variants: List[AppVariant] = client.apps.list_app_variants(app_id=app_id)
369
381
  except Exception as ex:
370
382
  raise ex
371
383
 
@@ -436,9 +448,14 @@ def remove_variant_cli(variant_name: str, app_folder: str):
436
448
  )
437
449
  @click.option("--app_folder", default=".")
438
450
  @click.option("--file_name", default=None, help="The name of the file to run")
451
+ @click.option(
452
+ "--overwrite",
453
+ is_flag=True,
454
+ help="Overwrite the existing variant if it exists",
455
+ )
439
456
  @click.pass_context
440
- def serve_cli(ctx, app_folder: str, file_name: str):
441
- """Adds a variant to the web ui and serves the API locally."""
457
+ def serve_cli(ctx, app_folder: str, file_name: str, overwrite: bool):
458
+ """Adds a variant to the web UI and serves the API locally."""
442
459
 
443
460
  if not file_name:
444
461
  if ctx.args:
@@ -449,35 +466,37 @@ def serve_cli(ctx, app_folder: str, file_name: str):
449
466
  error_msg += "or\n"
450
467
  error_msg += ">>> agenta variant serve <filename>.py"
451
468
  click.echo(click.style(f"{error_msg}", fg="red"))
452
- sys.exit(0)
469
+ sys.exit(1)
453
470
 
454
471
  try:
455
472
  config_check(app_folder)
456
473
  except Exception as e:
457
474
  click.echo(click.style("Failed during configuration check.", fg="red"))
458
475
  click.echo(click.style(f"Error message: {str(e)}", fg="red"))
459
- return
476
+ sys.exit(1)
460
477
 
461
478
  try:
462
479
  host = get_host(app_folder)
463
480
  except Exception as e:
464
481
  click.echo(click.style("Failed to retrieve the host.", fg="red"))
465
482
  click.echo(click.style(f"Error message: {str(e)}", fg="red"))
466
- return
483
+ sys.exit(1)
467
484
 
468
485
  try:
469
486
  api_key = helper.get_global_config("api_key")
470
487
  except Exception as e:
471
488
  click.echo(click.style("Failed to retrieve the api key.", fg="red"))
472
489
  click.echo(click.style(f"Error message: {str(e)}", fg="red"))
473
- return
490
+ sys.exit(1)
474
491
 
475
492
  try:
476
- variant_id = add_variant(app_folder=app_folder, file_name=file_name, host=host)
493
+ variant_id = add_variant(
494
+ app_folder=app_folder, file_name=file_name, host=host, overwrite=overwrite
495
+ )
477
496
  except Exception as e:
478
497
  click.echo(click.style("Failed to add variant.", fg="red"))
479
498
  click.echo(click.style(f"Error message: {str(e)}", fg="red"))
480
- return
499
+ sys.exit(1)
481
500
 
482
501
  if variant_id:
483
502
  try:
@@ -489,9 +508,11 @@ def serve_cli(ctx, app_folder: str, file_name: str):
489
508
  "- Second, try restarting the containers (if using Docker Compose)."
490
509
  )
491
510
  click.echo(click.style(f"{error_msg}", fg="red"))
511
+ sys.exit(1)
492
512
  except Exception as e:
493
513
  click.echo(click.style("Failed to start container with LLM app.", fg="red"))
494
514
  click.echo(click.style(f"Error message: {str(e)}", fg="red"))
515
+ sys.exit(1)
495
516
 
496
517
 
497
518
  @variant.command(name="list")
agenta/client/Readme.md CHANGED
@@ -7,90 +7,98 @@ Currently the models are manually copied from the backend code. This needs to ch
7
7
  To generate the client code using Fern, follow the steps below.
8
8
 
9
9
  1. Open a Terminal and navigate to the folder where this Readme.md file is. For example;
10
- ```
11
- $ cd agenta/agenta-cli/agenta/client
12
- ```
10
+ ```bash
11
+ cd agenta/agenta-cli/agenta/client
12
+ ```
13
13
 
14
14
  2. Next ensure you have installed Fern by executing the command;
15
- ```
16
- $ npm install -g fern-api
17
- ```
15
+ ```bash
16
+ npm install -g fern-api
17
+ ```
18
+
18
19
  3. Execute this command to initialize Fern to import and use the OpenAPI spec;
19
20
 
20
21
  > To use an OpenAPI spec, you can pass in the filepath or URL.
21
- > We'll be using a url to the openapi.json for [Agenta Cloud](https://cloud.agenta.ai)
22
+ > We'll need to log in to use fern.
23
+ > We'll be using a url to the openapi.json for [Agenta Cloud](https://cloud.agenta.ai).
24
+ > Alternatively, for `cloud-dev` we could use [Cloud Local](http://localhost).
22
25
 
23
- ```
26
+ ```bash
24
27
  fern init --openapi https://cloud.agenta.ai/api/openapi.json
28
+ # fern init --openapi http://localhost/api/openapi.json
25
29
  ```
26
30
 
27
31
  4. Add the Fern Python SDK;
28
- ```bash
29
- fern add fern-python-sdk
30
- ```
32
+ ```bash
33
+ fern add fern-python-sdk
34
+ ```
31
35
 
32
36
  5. Go to the generators.yml, which would look like this;
33
-
34
- ```yaml
35
- default-group: local
36
- groups:
37
- local:
38
- generators:
39
- - name: fernapi/fern-typescript-node-sdk
40
- version: 0.7.2
41
- output:
42
- location: local-file-system
43
- path: ../generated/typescript
44
- - name: fernapi/fern-python-sdk
45
- version: 0.6.0
46
- ```
47
-
48
- Replace the following;
49
-
50
- ```yaml
37
+ ```yaml
38
+ default-group: local
39
+ groups:
40
+ local:
41
+ generators:
51
42
  - name: fernapi/fern-typescript-node-sdk
52
- version: 0.7.2
53
- ```
54
-
55
- with this and delete it from the bottom of the file after;
56
-
57
- ```yaml
43
+ version: 0.9.5
44
+ output:
45
+ location: local-file-system
46
+ path: ../sdks/typescript
58
47
  - name: fernapi/fern-python-sdk
59
48
  version: 0.6.0
60
- ```
49
+ ```
61
50
 
62
- 6. Change the path from this `path: ../generated/typescript` to this path: `../backend`
51
+ 6. Remove `fernapi/fern-typescript-node-sdk`;
52
+ ```yaml
53
+ default-group: local
54
+ groups:
55
+ local:
56
+ generators:
57
+ - name: fernapi/fern-python-sdk
58
+ version: 3.10.6
59
+ ```
63
60
 
64
- Now your generators.yml should look like this;
65
- ```yaml
66
- default-group: local
67
- groups:
68
- local:
69
- generators:
70
- - name: fernapi/fern-python-sdk
71
- version: 0.6.0
72
- output:
73
- location: local-file-system
74
- path: ../backend
75
- ```
76
- <img width="1001" alt="image" src="https://github.com/Agenta-AI/agenta/assets/56418363/f537691d-8dbb-4363-b7c0-ecef9f464053">
61
+ 7. Update `fernapi/fern-python-sdk`, which would look like this;
62
+ ```yaml
63
+ default-group: local
64
+ groups:
65
+ local:
66
+ generators:
67
+ - name: fernapi/fern-python-sdk
68
+ version: 3.10.6
69
+ output:
70
+ location: local-file-system
71
+ path: ../backend
72
+ ```
73
+ <img width="1001" alt="image" src="https://github.com/Agenta-AI/agenta/assets/56418363/f537691d-8dbb-4363-b7c0-ecef9f464053">
77
74
 
78
75
 
79
- 7. Go to the fern.config.json file and change the value of "organization" to `agenta`
80
- <img width="593" alt="image" src="https://github.com/Agenta-AI/agenta/assets/56418363/0f44255e-50b5-4d78-863b-d33a3ec2eea0">
76
+ 8. Go to the fern.config.json file and change the value of "organization" to `agenta`
77
+ <img width="593" alt="image" src="https://github.com/Agenta-AI/agenta/assets/56418363/0f44255e-50b5-4d78-863b-d33a3ec2eea0">
81
78
 
82
79
 
83
- 9. Generate the client code
84
-
85
- ```bash
86
- fern generate
87
- ```
88
-
89
- 10. Change the timeout for the build_image function endpoint
90
- Go to the client.py in the generated code folder search for the `build_image` function in the AgentaApi class and change the timeout to 600.
91
- When done, it should look like this;
92
- <img width="995" alt="image" src="https://github.com/Agenta-AI/agenta/assets/56418363/8fab19e3-5226-405b-8a6f-4dcb6df588c9">
93
-
80
+ 9. Generate the client code
81
+ ```bash
82
+ fern generate
83
+ ```
94
84
 
85
+ 10. Go to `./backend/containers/client.py`, search for the `build_image` function in the AgentaApi class and update `timeout_in_seconds` to `600` in `request_options'. It should now look like this;
86
+ ```python
87
+ _response = self._client_wrapper.httpx_client.request(
88
+ "containers/build_image",
89
+ method="POST",
90
+ params={
91
+ "app_id": app_id,
92
+ "base_name": base_name,
93
+ },
94
+ data={},
95
+ files={
96
+ "tar_file": tar_file,
97
+ },
98
+ request_options={**request_options, "timeout_in_seconds": 600},
99
+ omit=OMIT,
100
+ )
101
+ ```
102
+ <img width="995" alt="image" src="https://github.com/Agenta-AI/agenta/assets/56418363/8fab19e3-5226-405b-8a6f-4dcb6df588c9">
95
103
 
96
- 11. Delete the fern folder.
104
+ 11. Delete the `./fern` folder.
agenta/client/api.py CHANGED
@@ -47,7 +47,7 @@ def add_variant_to_server(
47
47
  )
48
48
  for attempt in range(retries):
49
49
  try:
50
- response = client.add_variant_from_image(
50
+ response = client.apps.add_variant_from_image(
51
51
  app_id=app_id,
52
52
  variant_name=f"{base_name.lower()}.default",
53
53
  base_name=base_name,
@@ -55,7 +55,7 @@ def add_variant_to_server(
55
55
  docker_id=image.docker_id,
56
56
  tags=image.tags,
57
57
  )
58
- click.echo(click.style("\nVariant added successfully.", fg="green"))
58
+ click.echo(click.style("\nVariant added successfully!", fg="green"))
59
59
  return response
60
60
  except RequestException as e:
61
61
  if attempt < retries - 1: