agenta 0.12.3__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.
- agenta/__init__.py +64 -7
- agenta/cli/helper.py +7 -3
- agenta/cli/main.py +15 -50
- agenta/cli/variant_commands.py +50 -29
- agenta/client/Readme.md +72 -64
- agenta/client/api.py +2 -2
- agenta/client/backend/__init__.py +193 -22
- agenta/client/backend/access_control/__init__.py +1 -0
- agenta/client/backend/access_control/client.py +167 -0
- agenta/client/backend/apps/__init__.py +1 -0
- agenta/client/backend/apps/client.py +1691 -0
- agenta/client/backend/bases/__init__.py +1 -0
- agenta/client/backend/bases/client.py +190 -0
- agenta/client/backend/client.py +2508 -5712
- agenta/client/backend/configs/__init__.py +1 -0
- agenta/client/backend/configs/client.py +604 -0
- agenta/client/backend/containers/__init__.py +5 -0
- agenta/client/backend/containers/client.py +648 -0
- agenta/client/backend/containers/types/__init__.py +5 -0
- agenta/client/backend/{types → containers/types}/container_templates_response.py +1 -2
- agenta/client/backend/core/__init__.py +30 -0
- agenta/client/backend/core/client_wrapper.py +42 -9
- agenta/client/backend/core/file.py +70 -0
- agenta/client/backend/core/http_client.py +575 -0
- agenta/client/backend/core/jsonable_encoder.py +33 -39
- agenta/client/backend/core/pydantic_utilities.py +325 -0
- agenta/client/backend/core/query_encoder.py +60 -0
- agenta/client/backend/core/remove_none_from_dict.py +2 -2
- agenta/client/backend/core/request_options.py +35 -0
- agenta/client/backend/core/serialization.py +276 -0
- agenta/client/backend/environments/__init__.py +1 -0
- agenta/client/backend/environments/client.py +196 -0
- agenta/client/backend/evaluations/__init__.py +1 -0
- agenta/client/backend/evaluations/client.py +1469 -0
- agenta/client/backend/evaluators/__init__.py +1 -0
- agenta/client/backend/evaluators/client.py +1283 -0
- agenta/client/backend/observability/__init__.py +1 -0
- agenta/client/backend/observability/client.py +1286 -0
- agenta/client/backend/observability_v_1/__init__.py +5 -0
- agenta/client/backend/observability_v_1/client.py +763 -0
- agenta/client/backend/observability_v_1/types/__init__.py +7 -0
- agenta/client/backend/observability_v_1/types/format.py +5 -0
- agenta/client/backend/observability_v_1/types/query_analytics_response.py +7 -0
- agenta/client/backend/observability_v_1/types/query_traces_response.py +11 -0
- agenta/client/backend/scopes/__init__.py +1 -0
- agenta/client/backend/scopes/client.py +114 -0
- agenta/client/backend/testsets/__init__.py +1 -0
- agenta/client/backend/testsets/client.py +1284 -0
- agenta/client/backend/types/__init__.py +154 -26
- agenta/client/backend/types/agenta_node_dto.py +48 -0
- agenta/client/backend/types/agenta_node_dto_nodes_value.py +6 -0
- agenta/client/backend/types/agenta_nodes_response.py +30 -0
- agenta/client/backend/types/agenta_root_dto.py +30 -0
- agenta/client/backend/types/agenta_roots_response.py +30 -0
- agenta/client/backend/types/agenta_tree_dto.py +30 -0
- agenta/client/backend/types/agenta_trees_response.py +30 -0
- agenta/client/backend/types/aggregated_result.py +16 -31
- agenta/client/backend/types/aggregated_result_evaluator_config.py +8 -0
- agenta/client/backend/types/analytics_response.py +24 -0
- agenta/client/backend/types/app.py +17 -30
- agenta/client/backend/types/app_variant_response.py +36 -0
- agenta/client/backend/types/app_variant_revision.py +17 -32
- agenta/client/backend/types/base_output.py +13 -28
- agenta/client/backend/types/body_import_testset.py +15 -31
- agenta/client/backend/types/bucket_dto.py +26 -0
- agenta/client/backend/types/collect_status_response.py +22 -0
- agenta/client/backend/types/config_db.py +16 -31
- agenta/client/backend/types/config_dto.py +32 -0
- agenta/client/backend/types/config_response_model.py +32 -0
- agenta/client/backend/types/correct_answer.py +22 -0
- agenta/client/backend/types/create_app_output.py +13 -28
- agenta/client/backend/types/create_span.py +45 -0
- agenta/client/backend/types/create_trace_response.py +22 -0
- agenta/client/backend/types/docker_env_vars.py +13 -28
- agenta/client/backend/types/environment_output.py +22 -34
- agenta/client/backend/types/environment_output_extended.py +31 -0
- agenta/client/backend/types/environment_revision.py +26 -0
- agenta/client/backend/types/error.py +22 -0
- agenta/client/backend/types/evaluation.py +22 -33
- agenta/client/backend/types/evaluation_scenario.py +18 -33
- agenta/client/backend/types/evaluation_scenario_input.py +16 -31
- agenta/client/backend/types/evaluation_scenario_output.py +17 -30
- agenta/client/backend/types/evaluation_scenario_result.py +14 -29
- agenta/client/backend/types/evaluation_scenario_score_update.py +21 -0
- agenta/client/backend/types/evaluation_status_enum.py +11 -29
- agenta/client/backend/types/evaluation_type.py +3 -21
- agenta/client/backend/types/evaluator.py +20 -31
- agenta/client/backend/types/evaluator_config.py +21 -33
- agenta/client/backend/types/evaluator_mapping_output_interface.py +21 -0
- agenta/client/backend/types/evaluator_output_interface.py +21 -0
- agenta/client/backend/types/exception_dto.py +26 -0
- agenta/client/backend/types/get_config_response.py +23 -0
- agenta/client/backend/types/header_dto.py +22 -0
- agenta/client/backend/types/http_validation_error.py +14 -29
- agenta/client/backend/types/human_evaluation.py +18 -34
- agenta/client/backend/types/human_evaluation_scenario.py +22 -38
- agenta/client/backend/types/human_evaluation_scenario_input.py +13 -28
- agenta/client/backend/types/human_evaluation_scenario_output.py +13 -28
- agenta/client/backend/types/human_evaluation_scenario_update.py +30 -0
- agenta/client/backend/types/human_evaluation_update.py +22 -0
- agenta/client/backend/types/image.py +18 -32
- agenta/client/backend/types/invite_request.py +16 -30
- agenta/client/backend/types/legacy_analytics_response.py +29 -0
- agenta/client/backend/types/legacy_data_point.py +27 -0
- agenta/client/backend/types/lifecycle_dto.py +24 -0
- agenta/client/backend/types/link_dto.py +24 -0
- agenta/client/backend/types/list_api_keys_response.py +24 -0
- agenta/client/backend/types/llm_run_rate_limit.py +13 -28
- agenta/client/backend/types/llm_tokens.py +23 -0
- agenta/client/backend/types/metrics_dto.py +24 -0
- agenta/client/backend/types/new_human_evaluation.py +27 -0
- agenta/client/backend/types/new_testset.py +16 -31
- agenta/client/backend/types/node_dto.py +24 -0
- agenta/client/backend/types/node_type.py +19 -0
- agenta/client/backend/types/o_tel_context_dto.py +22 -0
- agenta/client/backend/types/o_tel_event_dto.py +23 -0
- agenta/client/backend/types/o_tel_extra_dto.py +26 -0
- agenta/client/backend/types/o_tel_link_dto.py +23 -0
- agenta/client/backend/types/o_tel_span_dto.py +37 -0
- agenta/client/backend/types/o_tel_span_kind.py +15 -0
- agenta/client/backend/types/o_tel_spans_response.py +24 -0
- agenta/client/backend/types/o_tel_status_code.py +8 -0
- agenta/client/backend/types/organization.py +22 -35
- agenta/client/backend/types/organization_output.py +13 -28
- agenta/client/backend/types/outputs.py +5 -0
- agenta/client/backend/types/parent_dto.py +21 -0
- agenta/client/backend/types/permission.py +41 -0
- agenta/client/backend/types/projects_response.py +28 -0
- agenta/client/backend/types/provider_key_dto.py +23 -0
- agenta/client/backend/types/provider_kind.py +21 -0
- agenta/client/backend/types/reference_dto.py +23 -0
- agenta/client/backend/types/reference_request_model.py +23 -0
- agenta/client/backend/types/result.py +18 -31
- agenta/client/backend/types/root_dto.py +21 -0
- agenta/client/backend/types/{human_evaluation_scenario_score.py → score.py} +1 -1
- agenta/client/backend/types/secret_dto.py +24 -0
- agenta/client/backend/types/{human_evaluation_scenario_update_score.py → secret_kind.py} +1 -1
- agenta/client/backend/types/secret_response_dto.py +27 -0
- agenta/client/backend/types/simple_evaluation_output.py +13 -28
- agenta/client/backend/types/span.py +39 -49
- agenta/client/backend/types/span_detail.py +44 -0
- agenta/client/backend/types/span_dto.py +54 -0
- agenta/client/backend/types/span_dto_nodes_value.py +9 -0
- agenta/client/backend/types/span_status_code.py +5 -0
- agenta/client/backend/types/span_variant.py +23 -0
- agenta/client/backend/types/status_code.py +5 -0
- agenta/client/backend/types/status_dto.py +23 -0
- agenta/client/backend/types/template.py +14 -29
- agenta/client/backend/types/template_image_info.py +21 -35
- agenta/client/backend/types/test_set_output_response.py +20 -33
- agenta/client/backend/types/test_set_simple_response.py +13 -28
- agenta/client/backend/types/time_dto.py +23 -0
- agenta/client/backend/types/trace_detail.py +44 -0
- agenta/client/backend/types/tree_dto.py +23 -0
- agenta/client/backend/types/tree_type.py +5 -0
- agenta/client/backend/types/update_app_output.py +22 -0
- agenta/client/backend/types/uri.py +13 -28
- agenta/client/backend/types/validation_error.py +13 -28
- agenta/client/backend/types/variant_action.py +14 -29
- agenta/client/backend/types/variant_action_enum.py +1 -19
- agenta/client/backend/types/with_pagination.py +26 -0
- agenta/client/backend/types/workspace_member_response.py +23 -0
- agenta/client/backend/types/workspace_permission.py +25 -0
- agenta/client/backend/types/workspace_response.py +29 -0
- agenta/client/backend/types/workspace_role.py +15 -0
- agenta/client/backend/types/workspace_role_response.py +23 -0
- agenta/client/backend/variants/__init__.py +5 -0
- agenta/client/backend/variants/client.py +2814 -0
- agenta/client/backend/variants/types/__init__.py +7 -0
- agenta/client/backend/variants/types/add_variant_from_base_and_config_response.py +8 -0
- agenta/client/backend/vault/__init__.py +1 -0
- agenta/client/backend/vault/client.py +685 -0
- agenta/client/client.py +1 -1
- agenta/config.py +0 -2
- agenta/config.toml +0 -1
- agenta/docker/docker-assets/Dockerfile.cloud.template +2 -1
- agenta/docker/docker-assets/Dockerfile.template +2 -1
- agenta/docker/docker_utils.py +11 -12
- agenta/sdk/__init__.py +58 -7
- agenta/sdk/agenta_init.py +182 -164
- agenta/sdk/assets.py +95 -0
- agenta/sdk/client.py +56 -0
- agenta/sdk/context/__init__.py +0 -0
- agenta/sdk/context/exporting.py +25 -0
- agenta/sdk/context/routing.py +27 -0
- agenta/sdk/context/tracing.py +28 -0
- agenta/sdk/decorators/__init__.py +0 -0
- agenta/sdk/decorators/routing.py +576 -0
- agenta/sdk/decorators/tracing.py +296 -0
- agenta/sdk/litellm/__init__.py +1 -0
- agenta/sdk/litellm/litellm.py +314 -0
- agenta/sdk/litellm/mockllm.py +27 -0
- agenta/sdk/litellm/mocks/__init__.py +26 -0
- agenta/sdk/managers/__init__.py +6 -0
- agenta/sdk/managers/config.py +208 -0
- agenta/sdk/managers/deployment.py +45 -0
- agenta/sdk/managers/secrets.py +38 -0
- agenta/sdk/managers/shared.py +639 -0
- agenta/sdk/managers/variant.py +182 -0
- agenta/sdk/managers/vault.py +16 -0
- agenta/sdk/middleware/__init__.py +0 -0
- agenta/sdk/middleware/auth.py +180 -0
- agenta/sdk/middleware/cache.py +47 -0
- agenta/sdk/middleware/config.py +255 -0
- agenta/sdk/middleware/cors.py +29 -0
- agenta/sdk/middleware/inline.py +38 -0
- agenta/sdk/middleware/mock.py +33 -0
- agenta/sdk/middleware/otel.py +40 -0
- agenta/sdk/middleware/vault.py +145 -0
- agenta/sdk/router.py +0 -7
- agenta/sdk/tracing/__init__.py +1 -0
- agenta/sdk/tracing/attributes.py +141 -0
- agenta/sdk/tracing/conventions.py +49 -0
- agenta/sdk/tracing/exporters.py +103 -0
- agenta/sdk/tracing/inline.py +1146 -0
- agenta/sdk/tracing/processors.py +121 -0
- agenta/sdk/tracing/spans.py +136 -0
- agenta/sdk/tracing/tracing.py +237 -0
- agenta/sdk/types.py +478 -74
- agenta/sdk/utils/__init__.py +0 -0
- agenta/sdk/utils/constants.py +1 -0
- agenta/sdk/utils/{helper/openai_cost.py → costs.py} +3 -0
- agenta/sdk/utils/exceptions.py +59 -0
- agenta/sdk/utils/globals.py +6 -10
- agenta/sdk/utils/helpers.py +8 -0
- agenta/sdk/utils/logging.py +21 -0
- agenta/sdk/utils/singleton.py +13 -0
- agenta/sdk/utils/timing.py +58 -0
- {agenta-0.12.3.dist-info → agenta-0.32.0a1.dist-info}/METADATA +98 -151
- agenta-0.32.0a1.dist-info/RECORD +263 -0
- {agenta-0.12.3.dist-info → agenta-0.32.0a1.dist-info}/WHEEL +1 -1
- agenta/client/backend/types/add_variant_from_base_and_config_response.py +0 -7
- agenta/client/backend/types/app_variant_output.py +0 -47
- agenta/client/backend/types/app_variant_output_extended.py +0 -50
- agenta/client/backend/types/delete_evaluation.py +0 -36
- agenta/client/backend/types/evaluation_webhook.py +0 -36
- agenta/client/backend/types/feedback.py +0 -40
- agenta/client/backend/types/get_config_reponse.py +0 -39
- agenta/client/backend/types/list_api_keys_output.py +0 -39
- agenta/client/backend/types/trace.py +0 -48
- agenta/sdk/agenta_decorator.py +0 -443
- agenta/sdk/context.py +0 -41
- agenta-0.12.3.dist-info/RECORD +0 -114
- {agenta-0.12.3.dist-info → agenta-0.32.0a1.dist-info}/entry_points.txt +0 -0
agenta/sdk/types.py
CHANGED
|
@@ -1,13 +1,32 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Dict, List, Optional, Any, Union
|
|
3
4
|
|
|
4
|
-
from pydantic import
|
|
5
|
+
from pydantic import ConfigDict, BaseModel, HttpUrl
|
|
5
6
|
|
|
7
|
+
from agenta.client.backend.types.agenta_node_dto import AgentaNodeDto
|
|
8
|
+
from agenta.client.backend.types.agenta_nodes_response import AgentaNodesResponse
|
|
9
|
+
from typing import Annotated, List, Union, Optional, Dict, Literal, Any
|
|
10
|
+
from pydantic import BaseModel, Field, root_validator
|
|
11
|
+
from agenta.sdk.assets import supported_llm_models
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class MultipleChoice:
|
|
16
|
+
choices: Union[List[str], Dict[str, List[str]]]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def MCField( # pylint: disable=invalid-name
|
|
20
|
+
default: str,
|
|
21
|
+
choices: Union[List[str], Dict[str, List[str]]],
|
|
22
|
+
) -> Field:
|
|
23
|
+
field = Field(default=default, description="ID of the model to use")
|
|
24
|
+
if isinstance(choices, dict):
|
|
25
|
+
field.json_schema_extra = {"choices": choices, "x-parameter": "grouped_choice"}
|
|
26
|
+
elif isinstance(choices, list):
|
|
27
|
+
field.json_schema_extra = {"choices": choices, "x-parameter": "choice"}
|
|
28
|
+
|
|
29
|
+
return field
|
|
11
30
|
|
|
12
31
|
|
|
13
32
|
class LLMTokenUsage(BaseModel):
|
|
@@ -16,95 +35,84 @@ class LLMTokenUsage(BaseModel):
|
|
|
16
35
|
total_tokens: int
|
|
17
36
|
|
|
18
37
|
|
|
19
|
-
class
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
38
|
+
class BaseResponse(BaseModel):
|
|
39
|
+
version: Optional[str] = "3.1"
|
|
40
|
+
data: Optional[Union[str, Dict[str, Any]]] = None
|
|
41
|
+
content_type: Optional[str] = "string"
|
|
42
|
+
tree: Optional[AgentaNodesResponse] = None
|
|
43
|
+
tree_id: Optional[str] = None
|
|
24
44
|
|
|
25
45
|
|
|
26
46
|
class DictInput(dict):
|
|
27
|
-
def __new__(cls, default_keys=None):
|
|
47
|
+
def __new__(cls, default_keys: Optional[List[str]] = None):
|
|
28
48
|
instance = super().__new__(cls, default_keys)
|
|
29
49
|
if default_keys is None:
|
|
30
50
|
default_keys = []
|
|
31
|
-
instance.data = [key for key in default_keys]
|
|
51
|
+
instance.data = [key for key in default_keys] # type: ignore
|
|
32
52
|
return instance
|
|
33
53
|
|
|
34
54
|
@classmethod
|
|
35
|
-
def
|
|
36
|
-
|
|
55
|
+
def __schema_type_properties__(cls) -> dict:
|
|
56
|
+
return {"x-parameter": "dict"}
|
|
37
57
|
|
|
38
58
|
|
|
39
59
|
class TextParam(str):
|
|
40
60
|
@classmethod
|
|
41
|
-
def
|
|
42
|
-
|
|
61
|
+
def __schema_type_properties__(cls) -> dict:
|
|
62
|
+
return {"x-parameter": "text", "type": "string"}
|
|
43
63
|
|
|
44
64
|
|
|
45
65
|
class BinaryParam(int):
|
|
46
66
|
def __new__(cls, value: bool = False):
|
|
47
67
|
instance = super().__new__(cls, int(value))
|
|
48
|
-
instance.default = value
|
|
68
|
+
instance.default = value # type: ignore
|
|
49
69
|
return instance
|
|
50
70
|
|
|
51
71
|
@classmethod
|
|
52
|
-
def
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
)
|
|
72
|
+
def __schema_type_properties__(cls) -> dict:
|
|
73
|
+
return {
|
|
74
|
+
"x-parameter": "bool",
|
|
75
|
+
"type": "boolean",
|
|
76
|
+
}
|
|
59
77
|
|
|
60
78
|
|
|
61
79
|
class IntParam(int):
|
|
62
80
|
def __new__(cls, default: int = 6, minval: float = 1, maxval: float = 10):
|
|
63
81
|
instance = super().__new__(cls, default)
|
|
64
|
-
instance.minval = minval
|
|
65
|
-
instance.maxval = maxval
|
|
82
|
+
instance.minval = minval # type: ignore
|
|
83
|
+
instance.maxval = maxval # type: ignore
|
|
66
84
|
return instance
|
|
67
85
|
|
|
68
86
|
@classmethod
|
|
69
|
-
def
|
|
70
|
-
|
|
71
|
-
{
|
|
72
|
-
"x-parameter": "int",
|
|
73
|
-
"type": "integer",
|
|
74
|
-
"minimum": 1,
|
|
75
|
-
"maximum": 10,
|
|
76
|
-
}
|
|
77
|
-
)
|
|
87
|
+
def __schema_type_properties__(cls) -> dict:
|
|
88
|
+
return {"x-parameter": "int", "type": "integer"}
|
|
78
89
|
|
|
79
90
|
|
|
80
91
|
class FloatParam(float):
|
|
81
92
|
def __new__(cls, default: float = 0.5, minval: float = 0.0, maxval: float = 1.0):
|
|
82
93
|
instance = super().__new__(cls, default)
|
|
83
|
-
instance.
|
|
84
|
-
instance.
|
|
94
|
+
instance.default = default # type: ignore
|
|
95
|
+
instance.minval = minval # type: ignore
|
|
96
|
+
instance.maxval = maxval # type: ignore
|
|
85
97
|
return instance
|
|
86
98
|
|
|
87
99
|
@classmethod
|
|
88
|
-
def
|
|
89
|
-
|
|
90
|
-
{
|
|
91
|
-
"x-parameter": "float",
|
|
92
|
-
"type": "number",
|
|
93
|
-
"minimum": 0.0,
|
|
94
|
-
"maximum": 1.0,
|
|
95
|
-
}
|
|
96
|
-
)
|
|
100
|
+
def __schema_type_properties__(cls) -> dict:
|
|
101
|
+
return {"x-parameter": "float", "type": "number"}
|
|
97
102
|
|
|
98
103
|
|
|
99
104
|
class MultipleChoiceParam(str):
|
|
100
|
-
def __new__(
|
|
101
|
-
|
|
105
|
+
def __new__(
|
|
106
|
+
cls, default: Optional[str] = None, choices: Optional[List[str]] = None
|
|
107
|
+
):
|
|
108
|
+
if default is not None and type(default) is list:
|
|
102
109
|
raise ValueError(
|
|
103
110
|
"The order of the parameters for MultipleChoiceParam is wrong! It's MultipleChoiceParam(default, choices) and not the opposite"
|
|
104
111
|
)
|
|
105
|
-
|
|
112
|
+
|
|
113
|
+
if not default and choices is not None:
|
|
106
114
|
# if a default value is not provided,
|
|
107
|
-
#
|
|
115
|
+
# set the first value in the choices list
|
|
108
116
|
default = choices[0]
|
|
109
117
|
|
|
110
118
|
if default is None and not choices:
|
|
@@ -112,24 +120,53 @@ class MultipleChoiceParam(str):
|
|
|
112
120
|
raise ValueError("You must provide either a default value or choices")
|
|
113
121
|
|
|
114
122
|
instance = super().__new__(cls, default)
|
|
115
|
-
instance.choices = choices
|
|
116
|
-
instance.default = default
|
|
123
|
+
instance.choices = choices # type: ignore
|
|
124
|
+
instance.default = default # type: ignore
|
|
117
125
|
return instance
|
|
118
126
|
|
|
119
127
|
@classmethod
|
|
120
|
-
def
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
def __schema_type_properties__(cls) -> dict:
|
|
129
|
+
return {"x-parameter": "choice", "type": "string", "enum": []}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class GroupedMultipleChoiceParam(str):
|
|
133
|
+
def __new__(
|
|
134
|
+
cls,
|
|
135
|
+
default: Optional[str] = None,
|
|
136
|
+
choices: Optional[Dict[str, List[str]]] = None,
|
|
137
|
+
):
|
|
138
|
+
if choices is None:
|
|
139
|
+
choices = {}
|
|
140
|
+
if default and not any(
|
|
141
|
+
default in choice_list for choice_list in choices.values()
|
|
142
|
+
):
|
|
143
|
+
if not choices:
|
|
144
|
+
print(
|
|
145
|
+
f"Warning: Default value {default} provided but choices are empty."
|
|
146
|
+
)
|
|
147
|
+
else:
|
|
148
|
+
raise ValueError(
|
|
149
|
+
f"Default value {default} is not in the provided choices"
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
if not default:
|
|
153
|
+
default_selected_choice = next(
|
|
154
|
+
(choices for choices in choices.values()), None
|
|
155
|
+
)
|
|
156
|
+
if default_selected_choice:
|
|
157
|
+
default = default_selected_choice[0]
|
|
128
158
|
|
|
159
|
+
instance = super().__new__(cls, default)
|
|
160
|
+
instance.choices = choices # type: ignore
|
|
161
|
+
instance.default = default # type: ignore
|
|
162
|
+
return instance
|
|
129
163
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
164
|
+
@classmethod
|
|
165
|
+
def __schema_type_properties__(cls) -> dict:
|
|
166
|
+
return {
|
|
167
|
+
"x-parameter": "grouped_choice",
|
|
168
|
+
"type": "string",
|
|
169
|
+
}
|
|
133
170
|
|
|
134
171
|
|
|
135
172
|
class MessagesInput(list):
|
|
@@ -144,30 +181,397 @@ class MessagesInput(list):
|
|
|
144
181
|
|
|
145
182
|
"""
|
|
146
183
|
|
|
147
|
-
def __new__(cls, messages: List[Dict[str, str]] =
|
|
148
|
-
instance = super().__new__(cls
|
|
149
|
-
instance.default = messages
|
|
184
|
+
def __new__(cls, messages: List[Dict[str, str]] = []):
|
|
185
|
+
instance = super().__new__(cls)
|
|
186
|
+
instance.default = messages # type: ignore
|
|
150
187
|
return instance
|
|
151
188
|
|
|
152
189
|
@classmethod
|
|
153
|
-
def
|
|
154
|
-
|
|
190
|
+
def __schema_type_properties__(cls) -> dict:
|
|
191
|
+
return {"x-parameter": "messages", "type": "array"}
|
|
155
192
|
|
|
156
193
|
|
|
157
194
|
class FileInputURL(HttpUrl):
|
|
195
|
+
def __new__(cls, url: str):
|
|
196
|
+
instance = super().__new__(cls, url)
|
|
197
|
+
instance.default = url # type: ignore
|
|
198
|
+
return instance
|
|
199
|
+
|
|
158
200
|
@classmethod
|
|
159
|
-
def
|
|
160
|
-
|
|
201
|
+
def __schema_type_properties__(cls) -> dict:
|
|
202
|
+
return {"x-parameter": "file_url", "type": "string"}
|
|
161
203
|
|
|
162
204
|
|
|
163
205
|
class Context(BaseModel):
|
|
164
|
-
|
|
165
|
-
extra = Extra.allow
|
|
206
|
+
model_config = ConfigDict(extra="allow")
|
|
166
207
|
|
|
167
208
|
def to_json(self):
|
|
168
|
-
return self.
|
|
209
|
+
return self.model_dump()
|
|
169
210
|
|
|
170
211
|
@classmethod
|
|
171
212
|
def from_json(cls, json_str: str):
|
|
172
213
|
data = json.loads(json_str)
|
|
173
214
|
return cls(**data)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class ReferencesResponse(BaseModel):
|
|
218
|
+
app_id: Optional[str] = None
|
|
219
|
+
app_slug: Optional[str] = None
|
|
220
|
+
variant_id: Optional[str] = None
|
|
221
|
+
variant_slug: Optional[str] = None
|
|
222
|
+
variant_version: Optional[int] = None
|
|
223
|
+
environment_id: Optional[str] = None
|
|
224
|
+
environment_slug: Optional[str] = None
|
|
225
|
+
environment_version: Optional[int] = None
|
|
226
|
+
|
|
227
|
+
def __str__(self):
|
|
228
|
+
return str(self.model_dump(exclude_none=True))
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class LifecyclesResponse(ReferencesResponse):
|
|
232
|
+
committed_at: Optional[str] = None
|
|
233
|
+
committed_by: Optional[str] = None
|
|
234
|
+
committed_by_id: Optional[str] = None
|
|
235
|
+
deployed_at: Optional[str] = None
|
|
236
|
+
deployed_by: Optional[str] = None
|
|
237
|
+
deployed_by_id: Optional[str] = None
|
|
238
|
+
|
|
239
|
+
def __str__(self):
|
|
240
|
+
return self.model_dump_json(indent=4)
|
|
241
|
+
|
|
242
|
+
def __repr__(self):
|
|
243
|
+
return self.__str__()
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
class ConfigurationResponse(LifecyclesResponse):
|
|
247
|
+
params: Dict[str, Any]
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
class DeploymentResponse(LifecyclesResponse):
|
|
251
|
+
pass
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
class Prompt(BaseModel):
|
|
255
|
+
temperature: float
|
|
256
|
+
model: str
|
|
257
|
+
max_tokens: int
|
|
258
|
+
prompt_system: str
|
|
259
|
+
prompt_user: str
|
|
260
|
+
top_p: float
|
|
261
|
+
frequency_penalty: float
|
|
262
|
+
presence_penalty: float
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
# -----------------------------------------------------
|
|
266
|
+
# New Prompt model
|
|
267
|
+
# -----------------------------------------------------
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class ToolCall(BaseModel):
|
|
271
|
+
id: str
|
|
272
|
+
type: Literal["function"] = "function"
|
|
273
|
+
function: Dict[str, str]
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
class Message(BaseModel):
|
|
277
|
+
role: Literal["system", "user", "assistant", "tool", "function"]
|
|
278
|
+
content: Optional[str] = None
|
|
279
|
+
name: Optional[str] = None
|
|
280
|
+
tool_calls: Optional[List[ToolCall]] = None
|
|
281
|
+
tool_call_id: Optional[str] = None
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
class ResponseFormatText(BaseModel):
|
|
285
|
+
type: Literal["text"]
|
|
286
|
+
"""The type of response format being defined: `text`"""
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
class ResponseFormatJSONObject(BaseModel):
|
|
290
|
+
type: Literal["json_object"]
|
|
291
|
+
"""The type of response format being defined: `json_object`"""
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
class JSONSchema(BaseModel):
|
|
295
|
+
name: str
|
|
296
|
+
"""The name of the response format."""
|
|
297
|
+
description: Optional[str] = None
|
|
298
|
+
"""A description of what the response format is for."""
|
|
299
|
+
schema_: Optional[Dict[str, object]] = Field(alias="schema", default=None)
|
|
300
|
+
"""The schema for the response format, described as a JSON Schema object."""
|
|
301
|
+
strict: Optional[bool] = None
|
|
302
|
+
"""Whether to enable strict schema adherence."""
|
|
303
|
+
|
|
304
|
+
model_config = {
|
|
305
|
+
"populate_by_name": True,
|
|
306
|
+
"json_schema_extra": {"required": ["name", "schema"]},
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
class ResponseFormatJSONSchema(BaseModel):
|
|
311
|
+
type: Literal["json_schema"]
|
|
312
|
+
"""The type of response format being defined: `json_schema`"""
|
|
313
|
+
json_schema: JSONSchema
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
ResponseFormat = Union[
|
|
317
|
+
ResponseFormatText, ResponseFormatJSONObject, ResponseFormatJSONSchema
|
|
318
|
+
]
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
class ModelConfig(BaseModel):
|
|
322
|
+
"""Configuration for model parameters"""
|
|
323
|
+
|
|
324
|
+
model: str = MCField(
|
|
325
|
+
default="gpt-3.5-turbo",
|
|
326
|
+
choices=supported_llm_models,
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
temperature: Optional[float] = Field(
|
|
330
|
+
default=1,
|
|
331
|
+
ge=0.0,
|
|
332
|
+
le=2.0,
|
|
333
|
+
description="What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic",
|
|
334
|
+
)
|
|
335
|
+
max_tokens: Optional[int] = Field(
|
|
336
|
+
default=-1,
|
|
337
|
+
ge=0,
|
|
338
|
+
description="The maximum number of tokens that can be generated in the chat completion",
|
|
339
|
+
)
|
|
340
|
+
top_p: Optional[float] = Field(
|
|
341
|
+
default=0.5,
|
|
342
|
+
ge=0.0,
|
|
343
|
+
le=1.0,
|
|
344
|
+
description="An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass",
|
|
345
|
+
)
|
|
346
|
+
frequency_penalty: Optional[float] = Field(
|
|
347
|
+
default=0,
|
|
348
|
+
ge=-2.0,
|
|
349
|
+
le=2.0,
|
|
350
|
+
description="Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far",
|
|
351
|
+
)
|
|
352
|
+
presence_penalty: Optional[float] = Field(
|
|
353
|
+
default=0,
|
|
354
|
+
ge=-2.0,
|
|
355
|
+
le=2.0,
|
|
356
|
+
description="Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far",
|
|
357
|
+
)
|
|
358
|
+
response_format: Optional[ResponseFormat] = Field(
|
|
359
|
+
default=None,
|
|
360
|
+
description="An object specifying the format that the model must output",
|
|
361
|
+
)
|
|
362
|
+
stream: Optional[bool] = Field(
|
|
363
|
+
default=None, description="If set, partial message deltas will be sent"
|
|
364
|
+
)
|
|
365
|
+
tools: Optional[List[Dict]] = Field(
|
|
366
|
+
default=None,
|
|
367
|
+
description="A list of tools the model may call. Currently, only functions are supported as a tool",
|
|
368
|
+
)
|
|
369
|
+
tool_choice: Optional[Union[Literal["none", "auto"], Dict]] = Field(
|
|
370
|
+
default=None, description="Controls which (if any) tool is called by the model"
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
class PromptTemplateError(Exception):
|
|
375
|
+
"""Base exception for all PromptTemplate errors"""
|
|
376
|
+
|
|
377
|
+
pass
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
class InputValidationError(PromptTemplateError):
|
|
381
|
+
"""Raised when input validation fails"""
|
|
382
|
+
|
|
383
|
+
def __init__(
|
|
384
|
+
self, message: str, missing: Optional[set] = None, extra: Optional[set] = None
|
|
385
|
+
):
|
|
386
|
+
self.missing = missing
|
|
387
|
+
self.extra = extra
|
|
388
|
+
super().__init__(message)
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
class TemplateFormatError(PromptTemplateError):
|
|
392
|
+
"""Raised when template formatting fails"""
|
|
393
|
+
|
|
394
|
+
def __init__(self, message: str, original_error: Optional[Exception] = None):
|
|
395
|
+
self.original_error = original_error
|
|
396
|
+
super().__init__(message)
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
class PromptTemplate(BaseModel):
|
|
400
|
+
"""A template for generating prompts with formatting capabilities"""
|
|
401
|
+
|
|
402
|
+
messages: List[Message] = Field(
|
|
403
|
+
default=[Message(role="system", content=""), Message(role="user", content="")]
|
|
404
|
+
)
|
|
405
|
+
system_prompt: Optional[str] = None
|
|
406
|
+
user_prompt: Optional[str] = None
|
|
407
|
+
template_format: Literal["fstring", "jinja2", "curly"] = Field(
|
|
408
|
+
default="fstring",
|
|
409
|
+
description="Format type for template variables: fstring {var}, jinja2 {{ var }}, or curly {{var}}",
|
|
410
|
+
)
|
|
411
|
+
input_keys: Optional[List[str]] = Field(
|
|
412
|
+
default=None,
|
|
413
|
+
description="Optional list of input keys for validation. If not provided, any inputs will be accepted",
|
|
414
|
+
)
|
|
415
|
+
llm_config: ModelConfig = Field(
|
|
416
|
+
default_factory=ModelConfig,
|
|
417
|
+
description="Configuration for the model parameters",
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
model_config = {
|
|
421
|
+
"json_schema_extra": {
|
|
422
|
+
"x-parameters": {
|
|
423
|
+
"prompt": "true",
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
@root_validator(pre=True)
|
|
429
|
+
def init_messages(cls, values):
|
|
430
|
+
if "messages" not in values:
|
|
431
|
+
messages = []
|
|
432
|
+
if "system_prompt" in values and values["system_prompt"]:
|
|
433
|
+
messages.append(Message(role="system", content=values["system_prompt"]))
|
|
434
|
+
if "user_prompt" in values and values["user_prompt"]:
|
|
435
|
+
messages.append(Message(role="user", content=values["user_prompt"]))
|
|
436
|
+
if messages:
|
|
437
|
+
values["messages"] = messages
|
|
438
|
+
return values
|
|
439
|
+
|
|
440
|
+
def _format_with_template(self, content: str, kwargs: Dict[str, Any]) -> str:
|
|
441
|
+
"""Internal method to format content based on template_format"""
|
|
442
|
+
try:
|
|
443
|
+
if self.template_format == "fstring":
|
|
444
|
+
return content.format(**kwargs)
|
|
445
|
+
elif self.template_format == "jinja2":
|
|
446
|
+
from jinja2 import Template, TemplateError
|
|
447
|
+
|
|
448
|
+
try:
|
|
449
|
+
return Template(content).render(**kwargs)
|
|
450
|
+
except TemplateError as e:
|
|
451
|
+
raise TemplateFormatError(
|
|
452
|
+
f"Jinja2 template error in content: '{content}'. Error: {str(e)}",
|
|
453
|
+
original_error=e,
|
|
454
|
+
)
|
|
455
|
+
elif self.template_format == "curly":
|
|
456
|
+
import re
|
|
457
|
+
|
|
458
|
+
result = content
|
|
459
|
+
for key, value in kwargs.items():
|
|
460
|
+
result = re.sub(r"\{\{" + key + r"\}\}", str(value), result)
|
|
461
|
+
if re.search(r"\{\{.*?\}\}", result):
|
|
462
|
+
unreplaced = re.findall(r"\{\{(.*?)\}\}", result)
|
|
463
|
+
raise TemplateFormatError(
|
|
464
|
+
f"Unreplaced variables in curly template: {unreplaced}"
|
|
465
|
+
)
|
|
466
|
+
return result
|
|
467
|
+
else:
|
|
468
|
+
raise TemplateFormatError(
|
|
469
|
+
f"Unknown template format: {self.template_format}"
|
|
470
|
+
)
|
|
471
|
+
except KeyError as e:
|
|
472
|
+
key = str(e).strip("'")
|
|
473
|
+
raise TemplateFormatError(
|
|
474
|
+
f"Missing required variable '{key}' in template: '{content}'"
|
|
475
|
+
)
|
|
476
|
+
except Exception as e:
|
|
477
|
+
raise TemplateFormatError(
|
|
478
|
+
f"Error formatting template '{content}': {str(e)}", original_error=e
|
|
479
|
+
)
|
|
480
|
+
|
|
481
|
+
def format(self, **kwargs) -> "PromptTemplate":
|
|
482
|
+
"""
|
|
483
|
+
Format the template with provided inputs.
|
|
484
|
+
Only validates against input_keys if they are specified.
|
|
485
|
+
|
|
486
|
+
Raises:
|
|
487
|
+
InputValidationError: If input validation fails
|
|
488
|
+
TemplateFormatError: If template formatting fails
|
|
489
|
+
"""
|
|
490
|
+
# Validate inputs if input_keys is set
|
|
491
|
+
if self.input_keys is not None:
|
|
492
|
+
missing = set(self.input_keys) - set(kwargs.keys())
|
|
493
|
+
extra = set(kwargs.keys()) - set(self.input_keys)
|
|
494
|
+
|
|
495
|
+
error_parts = []
|
|
496
|
+
if missing:
|
|
497
|
+
error_parts.append(
|
|
498
|
+
f"Missing required inputs: {', '.join(sorted(missing))}"
|
|
499
|
+
)
|
|
500
|
+
if extra:
|
|
501
|
+
error_parts.append(f"Unexpected inputs: {', '.join(sorted(extra))}")
|
|
502
|
+
|
|
503
|
+
if error_parts:
|
|
504
|
+
raise InputValidationError(
|
|
505
|
+
" | ".join(error_parts),
|
|
506
|
+
missing=missing if missing else None,
|
|
507
|
+
extra=extra if extra else None,
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
new_messages = []
|
|
511
|
+
for i, msg in enumerate(self.messages):
|
|
512
|
+
if msg.content:
|
|
513
|
+
try:
|
|
514
|
+
new_content = self._format_with_template(msg.content, kwargs)
|
|
515
|
+
except TemplateFormatError as e:
|
|
516
|
+
raise TemplateFormatError(
|
|
517
|
+
f"Error in message {i} ({msg.role}): {str(e)}",
|
|
518
|
+
original_error=e.original_error,
|
|
519
|
+
)
|
|
520
|
+
else:
|
|
521
|
+
new_content = None
|
|
522
|
+
|
|
523
|
+
new_messages.append(
|
|
524
|
+
Message(
|
|
525
|
+
role=msg.role,
|
|
526
|
+
content=new_content,
|
|
527
|
+
name=msg.name,
|
|
528
|
+
tool_calls=msg.tool_calls,
|
|
529
|
+
tool_call_id=msg.tool_call_id,
|
|
530
|
+
)
|
|
531
|
+
)
|
|
532
|
+
|
|
533
|
+
return PromptTemplate(
|
|
534
|
+
messages=new_messages,
|
|
535
|
+
template_format=self.template_format,
|
|
536
|
+
llm_config=self.llm_config,
|
|
537
|
+
input_keys=self.input_keys,
|
|
538
|
+
)
|
|
539
|
+
|
|
540
|
+
def to_openai_kwargs(self) -> dict:
|
|
541
|
+
"""Convert the prompt template to kwargs compatible with litellm/openai"""
|
|
542
|
+
kwargs = {
|
|
543
|
+
"model": self.llm_config.model,
|
|
544
|
+
"messages": [msg.dict(exclude_none=True) for msg in self.messages],
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
# Add optional parameters only if they are set
|
|
548
|
+
if self.llm_config.temperature is not None:
|
|
549
|
+
kwargs["temperature"] = self.llm_config.temperature
|
|
550
|
+
|
|
551
|
+
if self.llm_config.top_p is not None:
|
|
552
|
+
kwargs["top_p"] = self.llm_config.top_p
|
|
553
|
+
|
|
554
|
+
if self.llm_config.stream is not None:
|
|
555
|
+
kwargs["stream"] = self.llm_config.stream
|
|
556
|
+
|
|
557
|
+
if self.llm_config.max_tokens is not None:
|
|
558
|
+
kwargs["max_tokens"] = self.llm_config.max_tokens
|
|
559
|
+
|
|
560
|
+
if self.llm_config.frequency_penalty is not None:
|
|
561
|
+
kwargs["frequency_penalty"] = self.llm_config.frequency_penalty
|
|
562
|
+
|
|
563
|
+
if self.llm_config.presence_penalty is not None:
|
|
564
|
+
kwargs["presence_penalty"] = self.llm_config.presence_penalty
|
|
565
|
+
|
|
566
|
+
if self.llm_config.response_format:
|
|
567
|
+
kwargs["response_format"] = self.llm_config.response_format.dict(
|
|
568
|
+
by_alias=True
|
|
569
|
+
)
|
|
570
|
+
|
|
571
|
+
if self.llm_config.tools:
|
|
572
|
+
kwargs["tools"] = self.llm_config.tools
|
|
573
|
+
# Only set tool_choice if tools are present
|
|
574
|
+
if self.llm_config.tool_choice is not None:
|
|
575
|
+
kwargs["tool_choice"] = self.llm_config.tool_choice
|
|
576
|
+
|
|
577
|
+
return kwargs
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
TRUTHY = {"true", "1", "t", "y", "yes", "on", "enable", "enabled"}
|
|
@@ -49,6 +49,9 @@ MODEL_COST_PER_1K_TOKENS = {
|
|
|
49
49
|
"gpt-35-turbo-16k-completion": 0.004,
|
|
50
50
|
"gpt-35-turbo-16k-0613-completion": 0.004,
|
|
51
51
|
# Others
|
|
52
|
+
"text-embedding-ada-002": 0.1,
|
|
53
|
+
"text-ada-002": 0.1,
|
|
54
|
+
"adav2": 0.1,
|
|
52
55
|
"text-ada-001": 0.0004,
|
|
53
56
|
"ada": 0.0004,
|
|
54
57
|
"text-babbage-001": 0.0005,
|