agenta 0.12.7__py3-none-any.whl → 0.13.0a0__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 (123) hide show
  1. agenta/__init__.py +3 -2
  2. agenta/cli/helper.py +1 -1
  3. agenta/cli/main.py +1 -1
  4. agenta/cli/variant_commands.py +7 -5
  5. agenta/client/api.py +1 -1
  6. agenta/client/backend/__init__.py +78 -18
  7. agenta/client/backend/client.py +961 -5575
  8. agenta/client/backend/core/api_error.py +1 -3
  9. agenta/client/backend/core/datetime_utils.py +1 -3
  10. agenta/client/backend/core/jsonable_encoder.py +3 -9
  11. agenta/client/backend/resources/__init__.py +20 -0
  12. agenta/client/backend/resources/apps/__init__.py +2 -0
  13. agenta/client/backend/resources/apps/client.py +915 -0
  14. agenta/client/backend/resources/bases/__init__.py +2 -0
  15. agenta/client/backend/resources/bases/client.py +121 -0
  16. agenta/client/backend/resources/configs/__init__.py +2 -0
  17. agenta/client/backend/resources/configs/client.py +333 -0
  18. agenta/client/backend/resources/containers/__init__.py +5 -0
  19. agenta/client/backend/resources/containers/client.py +351 -0
  20. agenta/client/backend/resources/containers/types/__init__.py +5 -0
  21. agenta/client/backend/{types → resources/containers/types}/container_templates_response.py +1 -1
  22. agenta/client/backend/resources/environments/__init__.py +2 -0
  23. agenta/client/backend/resources/environments/client.py +119 -0
  24. agenta/client/backend/resources/evaluations/__init__.py +2 -0
  25. agenta/client/backend/resources/evaluations/client.py +948 -0
  26. agenta/client/backend/resources/evaluators/__init__.py +2 -0
  27. agenta/client/backend/resources/evaluators/client.py +554 -0
  28. agenta/client/backend/resources/observability/__init__.py +2 -0
  29. agenta/client/backend/resources/observability/client.py +1114 -0
  30. agenta/client/backend/resources/testsets/__init__.py +2 -0
  31. agenta/client/backend/resources/testsets/client.py +649 -0
  32. agenta/client/backend/resources/variants/__init__.py +5 -0
  33. agenta/client/backend/resources/variants/client.py +730 -0
  34. agenta/client/backend/resources/variants/types/__init__.py +5 -0
  35. agenta/client/backend/resources/variants/types/add_variant_from_base_and_config_response.py +7 -0
  36. agenta/client/backend/types/__init__.py +54 -22
  37. agenta/client/backend/types/aggregated_result.py +4 -12
  38. agenta/client/backend/types/aggregated_result_evaluator_config.py +7 -0
  39. agenta/client/backend/types/app.py +2 -10
  40. agenta/client/backend/types/{app_variant_output.py → app_variant_response.py} +6 -12
  41. agenta/client/backend/types/app_variant_revision.py +2 -10
  42. agenta/client/backend/types/base_output.py +2 -10
  43. agenta/client/backend/types/body_import_testset.py +2 -10
  44. agenta/client/backend/types/config_db.py +2 -10
  45. agenta/client/backend/types/create_app_output.py +2 -10
  46. agenta/client/backend/types/{trace.py → create_span.py} +21 -20
  47. agenta/client/backend/types/{delete_evaluation.py → create_trace_response.py} +5 -12
  48. agenta/client/backend/types/docker_env_vars.py +2 -10
  49. agenta/client/backend/types/environment_output.py +5 -11
  50. agenta/client/backend/types/environment_output_extended.py +37 -0
  51. agenta/client/backend/types/environment_revision.py +33 -0
  52. agenta/client/backend/types/error.py +29 -0
  53. agenta/client/backend/types/evaluation.py +8 -13
  54. agenta/client/backend/types/evaluation_scenario.py +2 -10
  55. agenta/client/backend/types/evaluation_scenario_input.py +2 -10
  56. agenta/client/backend/types/evaluation_scenario_output.py +6 -12
  57. agenta/client/backend/types/evaluation_scenario_result.py +2 -10
  58. agenta/client/backend/types/evaluation_scenario_score_update.py +28 -0
  59. agenta/client/backend/types/evaluation_status_enum.py +4 -0
  60. agenta/client/backend/types/evaluation_type.py +1 -3
  61. agenta/client/backend/types/evaluation_webhook.py +2 -10
  62. agenta/client/backend/types/evaluator.py +3 -10
  63. agenta/client/backend/types/evaluator_config.py +2 -10
  64. agenta/client/backend/types/feedback.py +2 -10
  65. agenta/client/backend/types/{get_config_reponse.py → get_config_response.py} +4 -12
  66. agenta/client/backend/types/http_validation_error.py +2 -10
  67. agenta/client/backend/types/human_evaluation.py +2 -10
  68. agenta/client/backend/types/human_evaluation_scenario.py +4 -12
  69. agenta/client/backend/types/human_evaluation_scenario_input.py +2 -10
  70. agenta/client/backend/types/human_evaluation_scenario_output.py +2 -10
  71. agenta/client/backend/types/human_evaluation_scenario_update.py +37 -0
  72. agenta/client/backend/types/human_evaluation_update.py +29 -0
  73. agenta/client/backend/types/image.py +3 -10
  74. agenta/client/backend/types/invite_request.py +3 -10
  75. agenta/client/backend/types/{list_api_keys_output.py → list_api_keys_response.py} +3 -11
  76. agenta/client/backend/types/llm_run_rate_limit.py +2 -10
  77. agenta/client/backend/types/llm_tokens.py +30 -0
  78. agenta/client/backend/types/new_human_evaluation.py +34 -0
  79. agenta/client/backend/types/new_testset.py +2 -10
  80. agenta/client/backend/types/organization.py +3 -10
  81. agenta/client/backend/types/organization_output.py +2 -10
  82. agenta/client/backend/types/permission.py +141 -0
  83. agenta/client/backend/types/result.py +4 -10
  84. agenta/client/backend/types/{human_evaluation_scenario_score.py → score.py} +1 -1
  85. agenta/client/backend/types/simple_evaluation_output.py +2 -10
  86. agenta/client/backend/types/span.py +20 -26
  87. agenta/client/backend/types/span_detail.py +44 -0
  88. agenta/client/backend/types/span_kind.py +49 -0
  89. agenta/client/backend/types/span_status_code.py +29 -0
  90. agenta/client/backend/types/span_variant.py +30 -0
  91. agenta/client/backend/types/template.py +2 -10
  92. agenta/client/backend/types/template_image_info.py +2 -10
  93. agenta/client/backend/types/test_set_output_response.py +2 -10
  94. agenta/client/backend/types/test_set_simple_response.py +2 -10
  95. agenta/client/backend/types/trace_detail.py +44 -0
  96. agenta/client/backend/types/uri.py +2 -10
  97. agenta/client/backend/types/validation_error.py +2 -10
  98. agenta/client/backend/types/variant_action.py +2 -10
  99. agenta/client/backend/types/variant_action_enum.py +1 -3
  100. agenta/client/backend/types/with_pagination.py +32 -0
  101. agenta/client/backend/types/workspace_member_response.py +30 -0
  102. agenta/client/backend/types/workspace_permission.py +32 -0
  103. agenta/client/backend/types/workspace_response.py +36 -0
  104. agenta/client/backend/types/workspace_role.py +41 -0
  105. agenta/client/backend/types/workspace_role_response.py +30 -0
  106. agenta/docker/docker_utils.py +1 -5
  107. agenta/sdk/__init__.py +3 -2
  108. agenta/sdk/agenta_decorator.py +68 -26
  109. agenta/sdk/agenta_init.py +50 -20
  110. agenta/sdk/tracing/context_manager.py +13 -0
  111. agenta/sdk/tracing/decorators.py +41 -0
  112. agenta/sdk/tracing/llm_tracing.py +203 -0
  113. agenta/sdk/tracing/logger.py +19 -0
  114. agenta/sdk/tracing/tasks_manager.py +130 -0
  115. agenta/sdk/types.py +0 -38
  116. {agenta-0.12.7.dist-info → agenta-0.13.0a0.dist-info}/METADATA +2 -1
  117. agenta-0.13.0a0.dist-info/RECORD +161 -0
  118. agenta/client/backend/types/add_variant_from_base_and_config_response.py +0 -7
  119. agenta/client/backend/types/app_variant_output_extended.py +0 -50
  120. agenta/client/backend/types/human_evaluation_scenario_update_score.py +0 -5
  121. agenta-0.12.7.dist-info/RECORD +0 -114
  122. {agenta-0.12.7.dist-info → agenta-0.13.0a0.dist-info}/WHEEL +0 -0
  123. {agenta-0.12.7.dist-info → agenta-0.13.0a0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,44 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ from ..core.datetime_utils import serialize_datetime
7
+ from .span import Span
8
+ from .span_kind import SpanKind
9
+ from .span_status_code import SpanStatusCode
10
+ from .span_variant import SpanVariant
11
+
12
+ try:
13
+ import pydantic.v1 as pydantic # type: ignore
14
+ except ImportError:
15
+ import pydantic # type: ignore
16
+
17
+
18
+ class TraceDetail(pydantic.BaseModel):
19
+ id: str
20
+ name: str
21
+ parent_span_id: typing.Optional[str]
22
+ created_at: dt.datetime
23
+ variant: SpanVariant
24
+ environment: typing.Optional[str]
25
+ spankind: SpanKind
26
+ status: SpanStatusCode
27
+ metadata: typing.Dict[str, typing.Any]
28
+ user_id: typing.Optional[str]
29
+ children: typing.Optional[typing.List[Span]]
30
+ content: typing.Dict[str, typing.Any]
31
+ config: typing.Dict[str, typing.Any]
32
+
33
+ def json(self, **kwargs: typing.Any) -> str:
34
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
35
+ return super().json(**kwargs_with_defaults)
36
+
37
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
38
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
39
+ return super().dict(**kwargs_with_defaults)
40
+
41
+ class Config:
42
+ frozen = True
43
+ smart_union = True
44
+ json_encoders = {dt.datetime: serialize_datetime}
@@ -15,19 +15,11 @@ class Uri(pydantic.BaseModel):
15
15
  uri: str
16
16
 
17
17
  def json(self, **kwargs: typing.Any) -> str:
18
- kwargs_with_defaults: typing.Any = {
19
- "by_alias": True,
20
- "exclude_unset": True,
21
- **kwargs,
22
- }
18
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
23
19
  return super().json(**kwargs_with_defaults)
24
20
 
25
21
  def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
26
- kwargs_with_defaults: typing.Any = {
27
- "by_alias": True,
28
- "exclude_unset": True,
29
- **kwargs,
30
- }
22
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
31
23
  return super().dict(**kwargs_with_defaults)
32
24
 
33
25
  class Config:
@@ -18,19 +18,11 @@ class ValidationError(pydantic.BaseModel):
18
18
  type: str
19
19
 
20
20
  def json(self, **kwargs: typing.Any) -> str:
21
- kwargs_with_defaults: typing.Any = {
22
- "by_alias": True,
23
- "exclude_unset": True,
24
- **kwargs,
25
- }
21
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
26
22
  return super().json(**kwargs_with_defaults)
27
23
 
28
24
  def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
29
- kwargs_with_defaults: typing.Any = {
30
- "by_alias": True,
31
- "exclude_unset": True,
32
- **kwargs,
33
- }
25
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
34
26
  return super().dict(**kwargs_with_defaults)
35
27
 
36
28
  class Config:
@@ -16,19 +16,11 @@ class VariantAction(pydantic.BaseModel):
16
16
  action: VariantActionEnum
17
17
 
18
18
  def json(self, **kwargs: typing.Any) -> str:
19
- kwargs_with_defaults: typing.Any = {
20
- "by_alias": True,
21
- "exclude_unset": True,
22
- **kwargs,
23
- }
19
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
24
20
  return super().json(**kwargs_with_defaults)
25
21
 
26
22
  def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
27
- kwargs_with_defaults: typing.Any = {
28
- "by_alias": True,
29
- "exclude_unset": True,
30
- **kwargs,
31
- }
23
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
32
24
  return super().dict(**kwargs_with_defaults)
33
25
 
34
26
  class Config:
@@ -14,9 +14,7 @@ class VariantActionEnum(str, enum.Enum):
14
14
  START = "START"
15
15
  STOP = "STOP"
16
16
 
17
- def visit(
18
- self, start: typing.Callable[[], T_Result], stop: typing.Callable[[], T_Result]
19
- ) -> T_Result:
17
+ def visit(self, start: typing.Callable[[], T_Result], stop: typing.Callable[[], T_Result]) -> T_Result:
20
18
  if self is VariantActionEnum.START:
21
19
  return start()
22
20
  if self is VariantActionEnum.STOP:
@@ -0,0 +1,32 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ from ..core.datetime_utils import serialize_datetime
7
+
8
+ try:
9
+ import pydantic.v1 as pydantic # type: ignore
10
+ except ImportError:
11
+ import pydantic # type: ignore
12
+
13
+
14
+ class WithPagination(pydantic.BaseModel):
15
+ data: typing.List[typing.Any]
16
+ total: int
17
+ page: int
18
+ page_size: int = pydantic.Field(alias="pageSize")
19
+
20
+ def json(self, **kwargs: typing.Any) -> str:
21
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
22
+ return super().json(**kwargs_with_defaults)
23
+
24
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
25
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
26
+ return super().dict(**kwargs_with_defaults)
27
+
28
+ class Config:
29
+ frozen = True
30
+ smart_union = True
31
+ allow_population_by_field_name = True
32
+ json_encoders = {dt.datetime: serialize_datetime}
@@ -0,0 +1,30 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ from ..core.datetime_utils import serialize_datetime
7
+ from .workspace_permission import WorkspacePermission
8
+
9
+ try:
10
+ import pydantic.v1 as pydantic # type: ignore
11
+ except ImportError:
12
+ import pydantic # type: ignore
13
+
14
+
15
+ class WorkspaceMemberResponse(pydantic.BaseModel):
16
+ user: typing.Dict[str, typing.Any]
17
+ roles: typing.List[WorkspacePermission]
18
+
19
+ def json(self, **kwargs: typing.Any) -> str:
20
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
21
+ return super().json(**kwargs_with_defaults)
22
+
23
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
24
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
25
+ return super().dict(**kwargs_with_defaults)
26
+
27
+ class Config:
28
+ frozen = True
29
+ smart_union = True
30
+ json_encoders = {dt.datetime: serialize_datetime}
@@ -0,0 +1,32 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ from ..core.datetime_utils import serialize_datetime
7
+ from .permission import Permission
8
+ from .workspace_role import WorkspaceRole
9
+
10
+ try:
11
+ import pydantic.v1 as pydantic # type: ignore
12
+ except ImportError:
13
+ import pydantic # type: ignore
14
+
15
+
16
+ class WorkspacePermission(pydantic.BaseModel):
17
+ role_name: WorkspaceRole
18
+ role_description: typing.Optional[str]
19
+ permissions: typing.Optional[typing.List[Permission]]
20
+
21
+ def json(self, **kwargs: typing.Any) -> str:
22
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
23
+ return super().json(**kwargs_with_defaults)
24
+
25
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
26
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
27
+ return super().dict(**kwargs_with_defaults)
28
+
29
+ class Config:
30
+ frozen = True
31
+ smart_union = True
32
+ json_encoders = {dt.datetime: serialize_datetime}
@@ -0,0 +1,36 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ from ..core.datetime_utils import serialize_datetime
7
+ from .workspace_member_response import WorkspaceMemberResponse
8
+
9
+ try:
10
+ import pydantic.v1 as pydantic # type: ignore
11
+ except ImportError:
12
+ import pydantic # type: ignore
13
+
14
+
15
+ class WorkspaceResponse(pydantic.BaseModel):
16
+ created_at: typing.Optional[dt.datetime]
17
+ updated_at: typing.Optional[dt.datetime]
18
+ id: str
19
+ name: str
20
+ description: typing.Optional[str]
21
+ type: typing.Optional[str]
22
+ organization: str
23
+ members: typing.Optional[typing.List[WorkspaceMemberResponse]]
24
+
25
+ def json(self, **kwargs: typing.Any) -> str:
26
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
27
+ return super().json(**kwargs_with_defaults)
28
+
29
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
30
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
31
+ return super().dict(**kwargs_with_defaults)
32
+
33
+ class Config:
34
+ frozen = True
35
+ smart_union = True
36
+ json_encoders = {dt.datetime: serialize_datetime}
@@ -0,0 +1,41 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import enum
4
+ import typing
5
+
6
+ T_Result = typing.TypeVar("T_Result")
7
+
8
+
9
+ class WorkspaceRole(str, enum.Enum):
10
+ """
11
+ An enumeration.
12
+ """
13
+
14
+ OWNER = "owner"
15
+ VIEWER = "viewer"
16
+ EDITOR = "editor"
17
+ EVALUATOR = "evaluator"
18
+ WORKSPACE_ADMIN = "workspace_admin"
19
+ DEPLOYMENT_MANAGER = "deployment_manager"
20
+
21
+ def visit(
22
+ self,
23
+ owner: typing.Callable[[], T_Result],
24
+ viewer: typing.Callable[[], T_Result],
25
+ editor: typing.Callable[[], T_Result],
26
+ evaluator: typing.Callable[[], T_Result],
27
+ workspace_admin: typing.Callable[[], T_Result],
28
+ deployment_manager: typing.Callable[[], T_Result],
29
+ ) -> T_Result:
30
+ if self is WorkspaceRole.OWNER:
31
+ return owner()
32
+ if self is WorkspaceRole.VIEWER:
33
+ return viewer()
34
+ if self is WorkspaceRole.EDITOR:
35
+ return editor()
36
+ if self is WorkspaceRole.EVALUATOR:
37
+ return evaluator()
38
+ if self is WorkspaceRole.WORKSPACE_ADMIN:
39
+ return workspace_admin()
40
+ if self is WorkspaceRole.DEPLOYMENT_MANAGER:
41
+ return deployment_manager()
@@ -0,0 +1,30 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ from ..core.datetime_utils import serialize_datetime
7
+ from .workspace_role import WorkspaceRole
8
+
9
+ try:
10
+ import pydantic.v1 as pydantic # type: ignore
11
+ except ImportError:
12
+ import pydantic # type: ignore
13
+
14
+
15
+ class WorkspaceRoleResponse(pydantic.BaseModel):
16
+ role_name: WorkspaceRole
17
+ role_description: typing.Optional[str]
18
+
19
+ def json(self, **kwargs: typing.Any) -> str:
20
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
21
+ return super().json(**kwargs_with_defaults)
22
+
23
+ def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
24
+ kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
25
+ return super().dict(**kwargs_with_defaults)
26
+
27
+ class Config:
28
+ frozen = True
29
+ smart_union = True
30
+ json_encoders = {dt.datetime: serialize_datetime}
@@ -3,11 +3,7 @@ import shutil
3
3
  import tarfile
4
4
  import tempfile
5
5
  from pathlib import Path
6
- from tempfile import TemporaryDirectory
7
6
 
8
- import docker
9
- from agenta.config import settings
10
- from docker.models.images import Image
11
7
 
12
8
  logger = logging.getLogger(__name__)
13
9
  logger.setLevel(logging.DEBUG)
@@ -15,7 +11,7 @@ logger.setLevel(logging.DEBUG)
15
11
  DEBUG = False
16
12
 
17
13
 
18
- def create_dockerfile(out_folder: Path):
14
+ def create_dockerfile(out_folder: Path) -> Path:
19
15
  """Creates a dockerfile based on the template in the out_folder.
20
16
 
21
17
  Arguments:
agenta/sdk/__init__.py CHANGED
@@ -9,13 +9,14 @@ from .types import (
9
9
  InFile,
10
10
  IntParam,
11
11
  MultipleChoiceParam,
12
- GroupedMultipleChoiceParam,
13
12
  TextParam,
14
13
  MessagesInput,
15
14
  FileInputURL,
16
15
  BinaryParam,
17
16
  )
18
- from .agenta_init import Config, init
17
+ from .tracing.decorators import span
18
+ from .agenta_init import Config, init, llm_tracing
19
19
  from .utils.helper.openai_cost import calculate_token_usage
20
20
 
21
+
21
22
  config = PreInitObject("agenta.config", Config)
@@ -5,15 +5,15 @@ import sys
5
5
  import time
6
6
  import inspect
7
7
  import argparse
8
+ import asyncio
8
9
  import traceback
9
10
  import functools
10
11
  from pathlib import Path
11
12
  from tempfile import NamedTemporaryFile
12
- from typing import Any, Callable, Dict, Optional, Tuple, List, Union
13
+ from typing import Any, Callable, Dict, Optional, Tuple, List
13
14
 
14
- from fastapi import Body, FastAPI, UploadFile
15
- from fastapi.responses import JSONResponse
16
15
  from fastapi.middleware.cors import CORSMiddleware
16
+ from fastapi import Body, FastAPI, UploadFile, HTTPException
17
17
 
18
18
  import agenta
19
19
  from .context import save_context
@@ -25,7 +25,6 @@ from .types import (
25
25
  InFile,
26
26
  IntParam,
27
27
  MultipleChoiceParam,
28
- GroupedMultipleChoiceParam,
29
28
  TextParam,
30
29
  MessagesInput,
31
30
  FileInputURL,
@@ -73,12 +72,34 @@ def entrypoint(func: Callable[..., Any]) -> Callable[..., Any]:
73
72
  config_params = agenta.config.all()
74
73
  ingestible_files = extract_ingestible_files(func_signature)
75
74
 
75
+ # Initialize tracing
76
+ tracing = agenta.llm_tracing()
77
+
76
78
  @functools.wraps(func)
77
79
  async def wrapper(*args, **kwargs) -> Any:
78
80
  func_params, api_config_params = split_kwargs(kwargs, config_params)
81
+
82
+ # Start tracing
83
+ tracing.start_parent_span(
84
+ name=func.__name__,
85
+ inputs=func_params,
86
+ config=api_config_params,
87
+ )
88
+
89
+ # Ingest files, prepare configurations and run llm app
79
90
  ingest_files(func_params, ingestible_files)
80
91
  agenta.config.set(**api_config_params)
81
- return await execute_function(func, *args, **func_params)
92
+ llm_result = await execute_function(
93
+ func, *args, params=func_params, config_params=config_params
94
+ )
95
+
96
+ # End trace recording
97
+ tracing.end_recording(
98
+ outputs=llm_result.dict(),
99
+ span=tracing.active_trace,
100
+ environment="playground", # type: ignore #NOTE: wrapper is only called in playground
101
+ )
102
+ return llm_result
82
103
 
83
104
  @functools.wraps(func)
84
105
  async def wrapper_deployed(*args, **kwargs) -> Any:
@@ -91,7 +112,27 @@ def entrypoint(func: Callable[..., Any]) -> Callable[..., Any]:
91
112
  agenta.config.pull(config_name=kwargs["config"])
92
113
  else:
93
114
  agenta.config.pull(config_name="default")
94
- return await execute_function(func, *args, **func_params)
115
+
116
+ config = agenta.config.all()
117
+
118
+ # Start tracing
119
+ tracing.start_parent_span(
120
+ name=func.__name__,
121
+ inputs=func_params,
122
+ config=config,
123
+ )
124
+
125
+ llm_result = await execute_function(
126
+ func, *args, params=func_params, config_params=config_params
127
+ )
128
+
129
+ # End trace recording
130
+ tracing.end_recording(
131
+ outputs=llm_result.dict(),
132
+ span=tracing.active_trace,
133
+ environment="playground", # type: ignore #NOTE: wrapper is only called in playground
134
+ )
135
+ return llm_result
95
136
 
96
137
  update_function_signature(wrapper, func_signature, config_params, ingestible_files)
97
138
  route = f"/{endpoint_name}"
@@ -153,9 +194,7 @@ def ingest_files(
153
194
  func_params[name] = ingest_file(func_params[name])
154
195
 
155
196
 
156
- async def execute_function(
157
- func: Callable[..., Any], *args, **func_params
158
- ) -> Union[Dict[str, Any], JSONResponse]:
197
+ async def execute_function(func: Callable[..., Any], *args, **func_params):
159
198
  """Execute the function and handle any exceptions."""
160
199
 
161
200
  try:
@@ -167,30 +206,32 @@ async def execute_function(
167
206
  is_coroutine_function = inspect.iscoroutinefunction(func)
168
207
  start_time = time.perf_counter()
169
208
  if is_coroutine_function:
170
- result = await func(*args, **func_params)
209
+ result = await func(*args, **func_params["params"])
171
210
  else:
172
- result = func(*args, **func_params)
211
+ result = func(*args, **func_params["params"])
212
+
173
213
  end_time = time.perf_counter()
174
214
  latency = end_time - start_time
175
215
 
176
216
  if isinstance(result, Context):
177
217
  save_context(result)
178
218
  if isinstance(result, Dict):
179
- return FuncResponse(**result, latency=round(latency, 4)).dict()
219
+ return FuncResponse(**result, latency=round(latency, 4))
180
220
  if isinstance(result, str):
181
- return FuncResponse(message=result, latency=round(latency, 4)).dict()
221
+ return FuncResponse(message=result, latency=round(latency, 4)) # type: ignore
182
222
  except Exception as e:
183
- return handle_exception(e)
223
+ handle_exception(e)
224
+ return FuncResponse(message="Unexpected error occurred", latency=0) # type: ignore
184
225
 
185
226
 
186
- def handle_exception(e: Exception) -> JSONResponse:
187
- """Handle exceptions and return a JSONResponse."""
227
+ def handle_exception(e: Exception):
228
+ """Handle exceptions."""
188
229
 
189
230
  status_code: int = e.status_code if hasattr(e, "status_code") else 500
190
- traceback_str = traceback.format_exception(e, value=e, tb=e.__traceback__)
191
- return JSONResponse(
231
+ traceback_str = traceback.format_exception(e, value=e, tb=e.__traceback__) # type: ignore
232
+ raise HTTPException(
192
233
  status_code=status_code,
193
- content={"error": str(e), "traceback": "".join(traceback_str)},
234
+ detail={"error": str(e), "traceback": "".join(traceback_str)},
194
235
  )
195
236
 
196
237
 
@@ -356,6 +397,14 @@ def handle_terminal_run(
356
397
  )
357
398
  agenta.config.set(**args_config_params)
358
399
 
400
+ loop = asyncio.get_event_loop()
401
+ result = loop.run_until_complete(
402
+ execute_function(
403
+ func, **{"params": args_func_params, "config_params": args_config_params}
404
+ )
405
+ )
406
+ print(result)
407
+
359
408
 
360
409
  def override_schema(openapi_schema: dict, func_name: str, endpoint: str, params: dict):
361
410
  """
@@ -397,13 +446,6 @@ def override_schema(openapi_schema: dict, func_name: str, endpoint: str, params:
397
446
  f"Body_{func_name}_{endpoint}_post"
398
447
  ]["properties"]
399
448
  for param_name, param_val in params.items():
400
- if isinstance(param_val, GroupedMultipleChoiceParam):
401
- subschema = find_in_schema(schema_to_override, param_name, "grouped_choice")
402
- assert (
403
- subschema
404
- ), f"GroupedMultipleChoiceParam '{param_name}' is in the parameters but could not be found in the openapi.json"
405
- subschema["choices"] = param_val.choices
406
- subschema["default"] = param_val.default
407
449
  if isinstance(param_val, MultipleChoiceParam):
408
450
  subschema = find_in_schema(schema_to_override, param_name, "choice")
409
451
  default = str(param_val)
agenta/sdk/agenta_init.py CHANGED
@@ -1,11 +1,14 @@
1
- from agenta.client.exceptions import APIRequestError
2
- from agenta.client.backend.client import AgentaApi
3
1
  import os
4
2
  import logging
5
3
  from typing import Any, Optional
6
4
 
7
5
  from .utils.globals import set_global
8
6
 
7
+ from agenta.client.backend.client import AgentaApi
8
+ from agenta.sdk.tracing.llm_tracing import Tracing
9
+ from agenta.client.exceptions import APIRequestError
10
+
11
+
9
12
  logger = logging.getLogger(__name__)
10
13
  logger.setLevel(logging.DEBUG)
11
14
 
@@ -40,6 +43,7 @@ class AgentaSingleton:
40
43
  base_name: Optional[str] = None,
41
44
  api_key: Optional[str] = None,
42
45
  base_id: Optional[str] = None,
46
+ app_id: Optional[str] = None,
43
47
  host: Optional[str] = None,
44
48
  **kwargs: Any,
45
49
  ) -> None:
@@ -75,30 +79,43 @@ class AgentaSingleton:
75
79
  )
76
80
  else:
77
81
  try:
78
- apps = client.list_apps(app_name=app_name)
79
- if len(apps) == 0:
80
- raise APIRequestError(f"App with name {app_name} not found")
81
-
82
- app_id = apps[0].app_id
83
- if not app_id:
84
- raise APIRequestError(
85
- f"App with name {app_name} does not exist on the server."
86
- )
87
-
88
- bases = client.list_bases(app_id=app_id, base_name=base_name)
89
- if len(bases) == 0:
90
- raise APIRequestError(f"No base was found for the app {app_id}")
91
-
92
- base_id = bases[0].base_id
82
+ app_id = self.get_app(app_name)
83
+ base_id = self.get_app_base(app_id, base_name)
93
84
  except Exception as ex:
94
85
  raise APIRequestError(
95
86
  f"Failed to get base id and/or app_id from the server with error: {ex}"
96
87
  )
88
+
97
89
  self.base_id = base_id
98
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")
99
93
  self.api_key = api_key
100
94
  self.config = Config(base_id=base_id, host=host)
101
95
 
96
+ def get_app(self, app_name: str) -> str:
97
+ apps = client.apps.list_apps(app_name=app_name)
98
+ if len(apps) == 0:
99
+ raise APIRequestError(f"App with name {app_name} not found")
100
+
101
+ app_id = apps[0].app_id
102
+ return app_id
103
+
104
+ def get_app_base(self, app_id: str, base_name: str) -> str:
105
+ bases = client.bases.list_bases(app_id=app_id, base_name=base_name)
106
+ if len(bases) == 0:
107
+ raise APIRequestError(f"No base was found for the app {app_id}")
108
+ return bases[0].base_id
109
+
110
+ def get_current_config(self):
111
+ """
112
+ Retrieves the current active configuration
113
+ """
114
+
115
+ if self._config_data is None:
116
+ raise RuntimeError("AgentaSingleton has not been initialized")
117
+ return self._config_data
118
+
102
119
 
103
120
  class Config:
104
121
  def __init__(self, base_id, host):
@@ -139,7 +156,7 @@ class Config:
139
156
  if not self.persist:
140
157
  return
141
158
  try:
142
- client.save_config(
159
+ client.configs.save_config(
143
160
  base_id=self.base_id,
144
161
  config_name=config_name,
145
162
  parameters=kwargs,
@@ -161,12 +178,12 @@ class Config:
161
178
  if self.persist:
162
179
  try:
163
180
  if environment_name:
164
- config = client.get_config(
181
+ config = client.configs.get_config(
165
182
  base_id=self.base_id, environment_name=environment_name
166
183
  )
167
184
 
168
185
  else:
169
- config = client.get_config(
186
+ config = client.configs.get_config(
170
187
  base_id=self.base_id,
171
188
  config_name=config_name,
172
189
  )
@@ -210,3 +227,16 @@ def init(app_name=None, base_name=None, **kwargs):
210
227
  singleton = AgentaSingleton()
211
228
  singleton.init(app_name=app_name, base_name=base_name, **kwargs)
212
229
  set_global(setup=singleton.setup, config=singleton.config)
230
+
231
+
232
+ def llm_tracing(max_workers: Optional[int] = None) -> Tracing:
233
+ """Function to start llm tracing."""
234
+
235
+ singleton = AgentaSingleton()
236
+ return Tracing(
237
+ base_url=singleton.host,
238
+ app_id=singleton.app_id, # type: ignore
239
+ variant_id=singleton.variant_id, # type: ignore
240
+ api_key=singleton.api_key,
241
+ max_workers=max_workers,
242
+ )
@@ -0,0 +1,13 @@
1
+ # Own Imports
2
+ from agenta.sdk.tracing.llm_tracing import Tracing
3
+
4
+
5
+ class TracingContextManager:
6
+ def __init__(self, tracing: Tracing):
7
+ ...
8
+
9
+ def __enter__(self):
10
+ ...
11
+
12
+ def __exit__(self, exc_type, exc_val, exc_tb):
13
+ ...