agenta 0.57.0__py3-none-any.whl → 0.63.2__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.
- agenta/__init__.py +12 -3
- agenta/client/__init__.py +4 -4
- agenta/client/backend/__init__.py +4 -4
- agenta/client/backend/api_keys/client.py +2 -2
- agenta/client/backend/billing/client.py +2 -2
- agenta/client/backend/billing/raw_client.py +2 -2
- agenta/client/backend/client.py +56 -48
- agenta/client/backend/core/client_wrapper.py +2 -2
- agenta/client/backend/core/file.py +3 -1
- agenta/client/backend/core/http_client.py +3 -3
- agenta/client/backend/core/pydantic_utilities.py +13 -3
- agenta/client/backend/human_evaluations/client.py +2 -2
- agenta/client/backend/human_evaluations/raw_client.py +2 -2
- agenta/client/backend/organization/client.py +46 -34
- agenta/client/backend/organization/raw_client.py +32 -26
- agenta/client/backend/raw_client.py +26 -26
- agenta/client/backend/testsets/client.py +18 -18
- agenta/client/backend/testsets/raw_client.py +30 -30
- agenta/client/backend/types/__init__.py +4 -4
- agenta/client/backend/types/account_request.py +3 -1
- agenta/client/backend/types/account_response.py +3 -1
- agenta/client/backend/types/agenta_node_dto.py +3 -1
- agenta/client/backend/types/agenta_nodes_response.py +3 -1
- agenta/client/backend/types/agenta_root_dto.py +3 -1
- agenta/client/backend/types/agenta_roots_response.py +3 -1
- agenta/client/backend/types/agenta_tree_dto.py +3 -1
- agenta/client/backend/types/agenta_trees_response.py +3 -1
- agenta/client/backend/types/aggregated_result.py +3 -1
- agenta/client/backend/types/analytics_response.py +3 -1
- agenta/client/backend/types/annotation.py +6 -4
- agenta/client/backend/types/annotation_create.py +3 -1
- agenta/client/backend/types/annotation_edit.py +3 -1
- agenta/client/backend/types/annotation_link.py +3 -1
- agenta/client/backend/types/annotation_link_response.py +3 -1
- agenta/client/backend/types/annotation_query.py +3 -1
- agenta/client/backend/types/annotation_query_request.py +3 -1
- agenta/client/backend/types/annotation_reference.py +3 -1
- agenta/client/backend/types/annotation_references.py +3 -1
- agenta/client/backend/types/annotation_response.py +3 -1
- agenta/client/backend/types/annotations_response.py +3 -1
- agenta/client/backend/types/app.py +3 -1
- agenta/client/backend/types/app_variant_response.py +3 -1
- agenta/client/backend/types/app_variant_revision.py +3 -1
- agenta/client/backend/types/artifact.py +6 -4
- agenta/client/backend/types/base_output.py +3 -1
- agenta/client/backend/types/body_fetch_workflow_revision.py +3 -1
- agenta/client/backend/types/body_import_testset.py +3 -1
- agenta/client/backend/types/bucket_dto.py +3 -1
- agenta/client/backend/types/collect_status_response.py +3 -1
- agenta/client/backend/types/config_db.py +3 -1
- agenta/client/backend/types/config_dto.py +3 -1
- agenta/client/backend/types/config_response_model.py +3 -1
- agenta/client/backend/types/correct_answer.py +3 -1
- agenta/client/backend/types/create_app_output.py +3 -1
- agenta/client/backend/types/custom_model_settings_dto.py +3 -1
- agenta/client/backend/types/custom_provider_dto.py +3 -1
- agenta/client/backend/types/custom_provider_kind.py +1 -1
- agenta/client/backend/types/custom_provider_settings_dto.py +3 -1
- agenta/client/backend/types/delete_evaluation.py +3 -1
- agenta/client/backend/types/environment_output.py +3 -1
- agenta/client/backend/types/environment_output_extended.py +3 -1
- agenta/client/backend/types/environment_revision.py +3 -1
- agenta/client/backend/types/error.py +3 -1
- agenta/client/backend/types/evaluation.py +3 -1
- agenta/client/backend/types/evaluation_scenario.py +3 -1
- agenta/client/backend/types/evaluation_scenario_input.py +3 -1
- agenta/client/backend/types/evaluation_scenario_output.py +3 -1
- agenta/client/backend/types/evaluation_scenario_result.py +3 -1
- agenta/client/backend/types/evaluator.py +6 -4
- agenta/client/backend/types/evaluator_config.py +6 -4
- agenta/client/backend/types/evaluator_flags.py +3 -1
- agenta/client/backend/types/evaluator_mapping_output_interface.py +3 -1
- agenta/client/backend/types/evaluator_output_interface.py +3 -1
- agenta/client/backend/types/evaluator_query.py +3 -1
- agenta/client/backend/types/evaluator_query_request.py +3 -1
- agenta/client/backend/types/evaluator_request.py +3 -1
- agenta/client/backend/types/evaluator_response.py +3 -1
- agenta/client/backend/types/evaluators_response.py +3 -1
- agenta/client/backend/types/exception_dto.py +3 -1
- agenta/client/backend/types/extended_o_tel_tracing_response.py +3 -1
- agenta/client/backend/types/get_config_response.py +3 -1
- agenta/client/backend/types/header.py +3 -1
- agenta/client/backend/types/http_validation_error.py +3 -1
- agenta/client/backend/types/human_evaluation.py +3 -1
- agenta/client/backend/types/human_evaluation_scenario.py +3 -1
- agenta/client/backend/types/human_evaluation_scenario_input.py +3 -1
- agenta/client/backend/types/human_evaluation_scenario_output.py +3 -1
- agenta/client/backend/types/invite_request.py +3 -1
- agenta/client/backend/types/legacy_analytics_response.py +3 -1
- agenta/client/backend/types/legacy_data_point.py +3 -1
- agenta/client/backend/types/legacy_evaluator.py +3 -1
- agenta/client/backend/types/legacy_scope_request.py +3 -1
- agenta/client/backend/types/legacy_scopes_response.py +3 -1
- agenta/client/backend/types/legacy_subscription_request.py +3 -1
- agenta/client/backend/types/legacy_user_request.py +3 -1
- agenta/client/backend/types/legacy_user_response.py +3 -1
- agenta/client/backend/types/lifecycle_dto.py +3 -1
- agenta/client/backend/types/link_dto.py +3 -1
- agenta/client/backend/types/list_api_keys_response.py +3 -1
- agenta/client/backend/types/llm_run_rate_limit.py +3 -1
- agenta/client/backend/types/meta_request.py +3 -1
- agenta/client/backend/types/metrics_dto.py +3 -1
- agenta/client/backend/types/new_testset.py +3 -1
- agenta/client/backend/types/node_dto.py +3 -1
- agenta/client/backend/types/o_tel_context_dto.py +3 -1
- agenta/client/backend/types/o_tel_event.py +6 -4
- agenta/client/backend/types/o_tel_event_dto.py +3 -1
- agenta/client/backend/types/o_tel_extra_dto.py +3 -1
- agenta/client/backend/types/o_tel_flat_span.py +6 -4
- agenta/client/backend/types/o_tel_link.py +6 -4
- agenta/client/backend/types/o_tel_link_dto.py +3 -1
- agenta/client/backend/types/o_tel_links_response.py +3 -1
- agenta/client/backend/types/o_tel_span.py +1 -1
- agenta/client/backend/types/o_tel_span_dto.py +3 -1
- agenta/client/backend/types/o_tel_spans_tree.py +3 -1
- agenta/client/backend/types/o_tel_tracing_data_response.py +3 -1
- agenta/client/backend/types/o_tel_tracing_request.py +3 -1
- agenta/client/backend/types/o_tel_tracing_response.py +3 -1
- agenta/client/backend/types/organization.py +3 -1
- agenta/client/backend/types/organization_details.py +3 -1
- agenta/client/backend/types/organization_membership_request.py +3 -1
- agenta/client/backend/types/organization_output.py +3 -1
- agenta/client/backend/types/organization_request.py +3 -1
- agenta/client/backend/types/parent_dto.py +3 -1
- agenta/client/backend/types/project_membership_request.py +3 -1
- agenta/client/backend/types/project_request.py +3 -1
- agenta/client/backend/types/project_scope.py +3 -1
- agenta/client/backend/types/projects_response.py +3 -1
- agenta/client/backend/types/reference.py +6 -4
- agenta/client/backend/types/reference_dto.py +3 -1
- agenta/client/backend/types/reference_request_model.py +3 -1
- agenta/client/backend/types/result.py +3 -1
- agenta/client/backend/types/root_dto.py +3 -1
- agenta/client/backend/types/scopes_response_model.py +3 -1
- agenta/client/backend/types/secret_dto.py +3 -1
- agenta/client/backend/types/secret_response_dto.py +3 -1
- agenta/client/backend/types/simple_evaluation_output.py +3 -1
- agenta/client/backend/types/span_dto.py +6 -4
- agenta/client/backend/types/standard_provider_dto.py +3 -1
- agenta/client/backend/types/standard_provider_settings_dto.py +3 -1
- agenta/client/backend/types/status_dto.py +3 -1
- agenta/client/backend/types/tags_request.py +3 -1
- agenta/client/backend/types/testcase_response.py +6 -4
- agenta/client/backend/types/testset.py +6 -4
- agenta/client/backend/types/{test_set_output_response.py → testset_output_response.py} +4 -2
- agenta/client/backend/types/testset_request.py +3 -1
- agenta/client/backend/types/testset_response.py +3 -1
- agenta/client/backend/types/{test_set_simple_response.py → testset_simple_response.py} +4 -2
- agenta/client/backend/types/testsets_response.py +3 -1
- agenta/client/backend/types/time_dto.py +3 -1
- agenta/client/backend/types/tree_dto.py +3 -1
- agenta/client/backend/types/update_app_output.py +3 -1
- agenta/client/backend/types/user_request.py +3 -1
- agenta/client/backend/types/validation_error.py +3 -1
- agenta/client/backend/types/workflow_artifact.py +6 -4
- agenta/client/backend/types/workflow_data.py +3 -1
- agenta/client/backend/types/workflow_flags.py +3 -1
- agenta/client/backend/types/workflow_request.py +3 -1
- agenta/client/backend/types/workflow_response.py +3 -1
- agenta/client/backend/types/workflow_revision.py +6 -4
- agenta/client/backend/types/workflow_revision_request.py +3 -1
- agenta/client/backend/types/workflow_revision_response.py +3 -1
- agenta/client/backend/types/workflow_revisions_response.py +3 -1
- agenta/client/backend/types/workflow_variant.py +6 -4
- agenta/client/backend/types/workflow_variant_request.py +3 -1
- agenta/client/backend/types/workflow_variant_response.py +3 -1
- agenta/client/backend/types/workflow_variants_response.py +3 -1
- agenta/client/backend/types/workflows_response.py +3 -1
- agenta/client/backend/types/workspace.py +3 -1
- agenta/client/backend/types/workspace_member_response.py +3 -1
- agenta/client/backend/types/workspace_membership_request.py +3 -1
- agenta/client/backend/types/workspace_permission.py +3 -1
- agenta/client/backend/types/workspace_request.py +3 -1
- agenta/client/backend/types/workspace_response.py +3 -1
- agenta/client/backend/workspace/client.py +2 -2
- agenta/client/client.py +102 -88
- agenta/sdk/__init__.py +52 -3
- agenta/sdk/agenta_init.py +43 -16
- agenta/sdk/assets.py +22 -15
- agenta/sdk/context/serving.py +20 -8
- agenta/sdk/context/tracing.py +40 -22
- agenta/sdk/contexts/__init__.py +0 -0
- agenta/sdk/contexts/routing.py +38 -0
- agenta/sdk/contexts/running.py +57 -0
- agenta/sdk/contexts/tracing.py +86 -0
- agenta/sdk/decorators/__init__.py +1 -0
- agenta/sdk/decorators/routing.py +284 -0
- agenta/sdk/decorators/running.py +692 -98
- agenta/sdk/decorators/serving.py +20 -21
- agenta/sdk/decorators/tracing.py +176 -131
- agenta/sdk/engines/__init__.py +0 -0
- agenta/sdk/engines/running/__init__.py +0 -0
- agenta/sdk/engines/running/utils.py +17 -0
- agenta/sdk/engines/tracing/__init__.py +1 -0
- agenta/sdk/engines/tracing/attributes.py +185 -0
- agenta/sdk/engines/tracing/conventions.py +49 -0
- agenta/sdk/engines/tracing/exporters.py +130 -0
- agenta/sdk/engines/tracing/inline.py +1154 -0
- agenta/sdk/engines/tracing/processors.py +190 -0
- agenta/sdk/engines/tracing/propagation.py +102 -0
- agenta/sdk/engines/tracing/spans.py +136 -0
- agenta/sdk/engines/tracing/tracing.py +324 -0
- agenta/sdk/evaluations/__init__.py +2 -0
- agenta/sdk/evaluations/metrics.py +37 -0
- agenta/sdk/evaluations/preview/__init__.py +0 -0
- agenta/sdk/evaluations/preview/evaluate.py +765 -0
- agenta/sdk/evaluations/preview/utils.py +861 -0
- agenta/sdk/evaluations/results.py +66 -0
- agenta/sdk/evaluations/runs.py +153 -0
- agenta/sdk/evaluations/scenarios.py +48 -0
- agenta/sdk/litellm/litellm.py +12 -0
- agenta/sdk/litellm/mockllm.py +6 -8
- agenta/sdk/litellm/mocks/__init__.py +5 -5
- agenta/sdk/managers/applications.py +304 -0
- agenta/sdk/managers/config.py +2 -2
- agenta/sdk/managers/evaluations.py +0 -0
- agenta/sdk/managers/evaluators.py +303 -0
- agenta/sdk/managers/secrets.py +161 -24
- agenta/sdk/managers/shared.py +3 -1
- agenta/sdk/managers/testsets.py +441 -0
- agenta/sdk/managers/vault.py +3 -3
- agenta/sdk/middleware/auth.py +0 -176
- agenta/sdk/middleware/vault.py +203 -8
- agenta/sdk/middlewares/__init__.py +0 -0
- agenta/sdk/middlewares/routing/__init__.py +0 -0
- agenta/sdk/middlewares/routing/auth.py +263 -0
- agenta/sdk/middlewares/routing/cors.py +30 -0
- agenta/sdk/middlewares/routing/otel.py +29 -0
- agenta/sdk/middlewares/running/__init__.py +0 -0
- agenta/sdk/middlewares/running/normalizer.py +321 -0
- agenta/sdk/middlewares/running/resolver.py +161 -0
- agenta/sdk/middlewares/running/vault.py +140 -0
- agenta/sdk/models/__init__.py +0 -0
- agenta/sdk/models/blobs.py +33 -0
- agenta/sdk/models/evaluations.py +119 -0
- agenta/sdk/models/git.py +126 -0
- agenta/sdk/models/shared.py +167 -0
- agenta/sdk/models/testsets.py +163 -0
- agenta/sdk/models/tracing.py +202 -0
- agenta/sdk/models/workflows.py +753 -0
- agenta/sdk/tracing/exporters.py +67 -17
- agenta/sdk/tracing/processors.py +97 -0
- agenta/sdk/tracing/propagation.py +3 -1
- agenta/sdk/tracing/spans.py +4 -0
- agenta/sdk/tracing/tracing.py +13 -13
- agenta/sdk/types.py +211 -17
- agenta/sdk/utils/cache.py +1 -1
- agenta/sdk/utils/client.py +38 -0
- agenta/sdk/utils/helpers.py +13 -12
- agenta/sdk/utils/logging.py +18 -78
- agenta/sdk/utils/references.py +23 -0
- agenta/sdk/workflows/builtin.py +600 -0
- agenta/sdk/workflows/configurations.py +22 -0
- agenta/sdk/workflows/errors.py +292 -0
- agenta/sdk/workflows/handlers.py +1791 -0
- agenta/sdk/workflows/interfaces.py +948 -0
- agenta/sdk/workflows/sandbox.py +118 -0
- agenta/sdk/workflows/utils.py +303 -6
- {agenta-0.57.0.dist-info → agenta-0.63.2.dist-info}/METADATA +33 -30
- agenta-0.63.2.dist-info/RECORD +421 -0
- agenta/sdk/middleware/adapt.py +0 -253
- agenta/sdk/middleware/base.py +0 -40
- agenta/sdk/middleware/flags.py +0 -40
- agenta/sdk/workflows/types.py +0 -472
- agenta-0.57.0.dist-info/RECORD +0 -371
- /agenta/sdk/{workflows → engines/running}/registry.py +0 -0
- {agenta-0.57.0.dist-info → agenta-0.63.2.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
from typing import Dict, Any, Callable, Optional
|
|
2
|
+
from uuid import uuid4, UUID
|
|
3
|
+
from traceback import print_exc
|
|
4
|
+
|
|
5
|
+
from agenta.sdk.utils.client import authed_api
|
|
6
|
+
from agenta.sdk.decorators.running import auto_workflow, is_workflow
|
|
7
|
+
from agenta.sdk.models.workflows import (
|
|
8
|
+
EvaluatorRevision,
|
|
9
|
+
#
|
|
10
|
+
EvaluatorRevisionResponse,
|
|
11
|
+
#
|
|
12
|
+
SimpleEvaluatorFlags,
|
|
13
|
+
SimpleEvaluatorData,
|
|
14
|
+
SimpleEvaluatorCreate,
|
|
15
|
+
SimpleEvaluatorEdit,
|
|
16
|
+
#
|
|
17
|
+
SimpleEvaluatorResponse,
|
|
18
|
+
#
|
|
19
|
+
Reference,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
from agenta.sdk.utils.references import get_slug_from_name_and_id
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
async def _retrieve_evaluator(
|
|
26
|
+
evaluator_id: Optional[UUID] = None,
|
|
27
|
+
evaluator_slug: Optional[str] = None,
|
|
28
|
+
evaluator_revision_id: Optional[UUID] = None,
|
|
29
|
+
evaluator_revision_slug: Optional[str] = None,
|
|
30
|
+
) -> Optional[EvaluatorRevision]:
|
|
31
|
+
payload = {
|
|
32
|
+
"evaluator_ref": (
|
|
33
|
+
{
|
|
34
|
+
"id": str(evaluator_id) if evaluator_id else None,
|
|
35
|
+
"slug": str(evaluator_slug),
|
|
36
|
+
}
|
|
37
|
+
if evaluator_id or evaluator_slug
|
|
38
|
+
else None
|
|
39
|
+
),
|
|
40
|
+
"evaluator_revision_ref": (
|
|
41
|
+
{
|
|
42
|
+
"id": str(evaluator_revision_id) if evaluator_revision_id else None,
|
|
43
|
+
"slug": evaluator_revision_slug,
|
|
44
|
+
}
|
|
45
|
+
if evaluator_revision_id or evaluator_revision_slug
|
|
46
|
+
else None
|
|
47
|
+
),
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# print(" --- payload:", payload)
|
|
51
|
+
|
|
52
|
+
response = authed_api()(
|
|
53
|
+
method="POST",
|
|
54
|
+
endpoint=f"/preview/evaluators/revisions/retrieve",
|
|
55
|
+
json=payload,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
response.raise_for_status()
|
|
59
|
+
|
|
60
|
+
evaluator_revision_response = EvaluatorRevisionResponse(**response.json())
|
|
61
|
+
|
|
62
|
+
evaluator_revision = evaluator_revision_response.evaluator_revision
|
|
63
|
+
|
|
64
|
+
# print(" --- evaluator_revision:", evaluator_revision)
|
|
65
|
+
|
|
66
|
+
return evaluator_revision
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
async def aretrieve(
|
|
70
|
+
evaluator_revision_id: Optional[UUID] = None,
|
|
71
|
+
) -> Optional[EvaluatorRevision]:
|
|
72
|
+
# print("\n--------- RETRIEVE EVALUATOR")
|
|
73
|
+
response = await _retrieve_evaluator(
|
|
74
|
+
evaluator_revision_id=evaluator_revision_id,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
return response
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
async def aupsert(
|
|
81
|
+
*,
|
|
82
|
+
evaluator_id: Optional[UUID] = None,
|
|
83
|
+
evaluator_slug: Optional[str] = None,
|
|
84
|
+
evaluator_revision_id: Optional[UUID] = None,
|
|
85
|
+
evaluator_revision_slug: Optional[str] = None,
|
|
86
|
+
#
|
|
87
|
+
handler: Callable,
|
|
88
|
+
script: Optional[str] = None,
|
|
89
|
+
parameters: Optional[Dict[str, Any]] = None,
|
|
90
|
+
#
|
|
91
|
+
name: Optional[str] = None,
|
|
92
|
+
description: Optional[str] = None,
|
|
93
|
+
) -> Optional[UUID]:
|
|
94
|
+
# print("\n--------- UPSERT EVALUATOR")
|
|
95
|
+
try:
|
|
96
|
+
if not is_workflow(handler):
|
|
97
|
+
evaluator_workflow = auto_workflow(
|
|
98
|
+
handler,
|
|
99
|
+
#
|
|
100
|
+
script=script,
|
|
101
|
+
parameters=parameters,
|
|
102
|
+
#
|
|
103
|
+
name=name,
|
|
104
|
+
description=description,
|
|
105
|
+
)
|
|
106
|
+
else:
|
|
107
|
+
evaluator_workflow = handler
|
|
108
|
+
|
|
109
|
+
req = await evaluator_workflow.inspect()
|
|
110
|
+
|
|
111
|
+
legacy_application_flags = SimpleEvaluatorFlags(**req.flags)
|
|
112
|
+
|
|
113
|
+
simple_evaluator_data = SimpleEvaluatorData(
|
|
114
|
+
**(
|
|
115
|
+
req.interface.model_dump(mode="json", exclude_none=True)
|
|
116
|
+
if req and req.interface
|
|
117
|
+
else {}
|
|
118
|
+
),
|
|
119
|
+
**(
|
|
120
|
+
req.configuration.model_dump(mode="json", exclude_none=True)
|
|
121
|
+
if req and req.configuration
|
|
122
|
+
else {}
|
|
123
|
+
),
|
|
124
|
+
)
|
|
125
|
+
# print(" ---:", simple_evaluator_data.model_dump(mode="json", exclude_none=True))
|
|
126
|
+
|
|
127
|
+
retrieve_response = None
|
|
128
|
+
|
|
129
|
+
if req.references is not None:
|
|
130
|
+
_evaluator_revision_ref = req.references.get("evaluator_revision", {})
|
|
131
|
+
if isinstance(_evaluator_revision_ref, Reference):
|
|
132
|
+
_evaluator_revision_ref = _evaluator_revision_ref.model_dump(
|
|
133
|
+
mode="json",
|
|
134
|
+
exclude_none=True,
|
|
135
|
+
)
|
|
136
|
+
if not isinstance(_evaluator_revision_ref, dict):
|
|
137
|
+
_evaluator_revision_ref = {}
|
|
138
|
+
|
|
139
|
+
_evaluator_revision_id = _evaluator_revision_ref.get("id")
|
|
140
|
+
_evaluator_revision_slug = _evaluator_revision_ref.get("slug")
|
|
141
|
+
|
|
142
|
+
evaluator_revision_id = evaluator_revision_id or _evaluator_revision_id
|
|
143
|
+
evaluator_revision_slug = (
|
|
144
|
+
evaluator_revision_slug or _evaluator_revision_slug
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
_evaluator_ref = req.references.get("evaluator", {})
|
|
148
|
+
if isinstance(_evaluator_ref, Reference):
|
|
149
|
+
_evaluator_ref = _evaluator_ref.model_dump(
|
|
150
|
+
mode="json",
|
|
151
|
+
exclude_none=True,
|
|
152
|
+
)
|
|
153
|
+
if not isinstance(_evaluator_ref, dict):
|
|
154
|
+
_evaluator_ref = {}
|
|
155
|
+
|
|
156
|
+
_evaluator_id = _evaluator_ref.get("id")
|
|
157
|
+
_evaluator_slug = _evaluator_ref.get("slug")
|
|
158
|
+
|
|
159
|
+
evaluator_id = evaluator_id or _evaluator_id
|
|
160
|
+
evaluator_slug = evaluator_slug or _evaluator_slug
|
|
161
|
+
|
|
162
|
+
revision = req.data.revision if req and req.data else None
|
|
163
|
+
if revision:
|
|
164
|
+
name = name or revision.get("name")
|
|
165
|
+
description = description or revision.get("description")
|
|
166
|
+
|
|
167
|
+
name = (
|
|
168
|
+
name or req.data.revision.get("name")
|
|
169
|
+
if req and req.data and req.data.revision
|
|
170
|
+
else None
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
description = (
|
|
174
|
+
description or req.data.revision.get("description")
|
|
175
|
+
if req and req.data and req.data.revision
|
|
176
|
+
else None
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
evaluator_slug = (
|
|
180
|
+
evaluator_slug
|
|
181
|
+
or get_slug_from_name_and_id(
|
|
182
|
+
name=name,
|
|
183
|
+
id=evaluator_id or uuid4(),
|
|
184
|
+
)
|
|
185
|
+
if name
|
|
186
|
+
else uuid4().hex[-12:]
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
# print(
|
|
190
|
+
# evaluator_id,
|
|
191
|
+
# evaluator_slug,
|
|
192
|
+
# evaluator_revision_id,
|
|
193
|
+
# evaluator_revision_slug,
|
|
194
|
+
# )
|
|
195
|
+
|
|
196
|
+
if evaluator_revision_id or evaluator_revision_slug:
|
|
197
|
+
retrieve_response = await _retrieve_evaluator(
|
|
198
|
+
evaluator_revision_id=evaluator_revision_id,
|
|
199
|
+
evaluator_revision_slug=evaluator_revision_slug,
|
|
200
|
+
)
|
|
201
|
+
elif evaluator_id or evaluator_slug:
|
|
202
|
+
retrieve_response = await _retrieve_evaluator(
|
|
203
|
+
evaluator_id=evaluator_id,
|
|
204
|
+
evaluator_slug=evaluator_slug,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
except Exception as e:
|
|
208
|
+
print("[ERROR]: Failed to prepare evaluator:")
|
|
209
|
+
print_exc()
|
|
210
|
+
return None
|
|
211
|
+
|
|
212
|
+
# print("Retrieve response:", retrieve_response)
|
|
213
|
+
|
|
214
|
+
if retrieve_response and retrieve_response.id and retrieve_response.evaluator_id:
|
|
215
|
+
evaluator_id = retrieve_response.evaluator_id
|
|
216
|
+
# print(" --- Updating evaluator...", evaluator_id)
|
|
217
|
+
evaluator_edit_request = SimpleEvaluatorEdit(
|
|
218
|
+
id=evaluator_id,
|
|
219
|
+
#
|
|
220
|
+
name=name,
|
|
221
|
+
description=description,
|
|
222
|
+
#
|
|
223
|
+
flags=legacy_application_flags,
|
|
224
|
+
#
|
|
225
|
+
data=simple_evaluator_data,
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
# print(" --- evaluator_edit_request:", evaluator_edit_request)
|
|
229
|
+
|
|
230
|
+
response = authed_api()(
|
|
231
|
+
method="PUT",
|
|
232
|
+
endpoint=f"/preview/simple/evaluators/{evaluator_id}",
|
|
233
|
+
json={
|
|
234
|
+
"evaluator": evaluator_edit_request.model_dump(
|
|
235
|
+
mode="json",
|
|
236
|
+
exclude_none=True,
|
|
237
|
+
)
|
|
238
|
+
},
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
# print(" --- response:", response.status_code, response.text)
|
|
242
|
+
|
|
243
|
+
try:
|
|
244
|
+
response.raise_for_status()
|
|
245
|
+
except Exception as e:
|
|
246
|
+
print("[ERROR]: Failed to update evaluator:", e)
|
|
247
|
+
print_exc()
|
|
248
|
+
return None
|
|
249
|
+
|
|
250
|
+
else:
|
|
251
|
+
# print(" --- Creating evaluator...")
|
|
252
|
+
evaluator_create_request = SimpleEvaluatorCreate(
|
|
253
|
+
slug=evaluator_slug or uuid4().hex[-12:],
|
|
254
|
+
#
|
|
255
|
+
name=name,
|
|
256
|
+
description=description,
|
|
257
|
+
#
|
|
258
|
+
flags=legacy_application_flags,
|
|
259
|
+
#
|
|
260
|
+
data=simple_evaluator_data,
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
# print(" --- evaluator_create_request:", evaluator_create_request)
|
|
264
|
+
|
|
265
|
+
response = authed_api()(
|
|
266
|
+
method="POST",
|
|
267
|
+
endpoint="/preview/simple/evaluators/",
|
|
268
|
+
json={
|
|
269
|
+
"evaluator": evaluator_create_request.model_dump(
|
|
270
|
+
mode="json",
|
|
271
|
+
exclude_none=True,
|
|
272
|
+
)
|
|
273
|
+
},
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
# print(" --- response:", response.status_code, response.text)
|
|
277
|
+
|
|
278
|
+
try:
|
|
279
|
+
response.raise_for_status()
|
|
280
|
+
except Exception as e:
|
|
281
|
+
print("[ERROR]: Failed to create evaluator:", e)
|
|
282
|
+
print_exc()
|
|
283
|
+
return None
|
|
284
|
+
|
|
285
|
+
evaluator_response = SimpleEvaluatorResponse(**response.json())
|
|
286
|
+
|
|
287
|
+
evaluator = evaluator_response.evaluator
|
|
288
|
+
|
|
289
|
+
if not evaluator or not evaluator.id:
|
|
290
|
+
return None
|
|
291
|
+
|
|
292
|
+
# print(" --- evaluator:", evaluator)
|
|
293
|
+
|
|
294
|
+
evaluator_revision = await _retrieve_evaluator(
|
|
295
|
+
evaluator_id=evaluator.id,
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
if not evaluator_revision or not evaluator_revision.id:
|
|
299
|
+
return None
|
|
300
|
+
|
|
301
|
+
# print(evaluator_revision, "----------")
|
|
302
|
+
|
|
303
|
+
return evaluator_revision.id
|
agenta/sdk/managers/secrets.py
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import re
|
|
2
2
|
from typing import Optional, Dict, Any, List
|
|
3
3
|
|
|
4
|
-
from agenta.sdk.
|
|
4
|
+
from agenta.sdk.utils.logging import get_module_logger
|
|
5
|
+
from agenta.sdk.contexts.routing import RoutingContext
|
|
6
|
+
from agenta.sdk.contexts.running import RunningContext
|
|
5
7
|
from agenta.sdk.assets import model_to_provider_mapping as _standard_providers
|
|
6
8
|
|
|
9
|
+
from agenta.sdk.middlewares.running.vault import get_secrets
|
|
10
|
+
|
|
11
|
+
import agenta as ag
|
|
12
|
+
|
|
13
|
+
log = get_module_logger(__name__)
|
|
14
|
+
|
|
7
15
|
|
|
8
16
|
class SecretsManager:
|
|
9
17
|
@staticmethod
|
|
10
18
|
def get_from_route() -> Optional[List[Dict[str, Any]]]:
|
|
11
|
-
context =
|
|
19
|
+
context = RoutingContext.get()
|
|
12
20
|
|
|
13
21
|
secrets = context.secrets
|
|
14
22
|
|
|
15
23
|
if not secrets:
|
|
16
|
-
return
|
|
24
|
+
return []
|
|
17
25
|
|
|
18
26
|
return secrets
|
|
19
27
|
|
|
@@ -119,11 +127,17 @@ class SecretsManager:
|
|
|
119
127
|
# The reason is that custom providers are in fact openai compatible providers
|
|
120
128
|
# They need to be passed in litellm as openai/modelname
|
|
121
129
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
130
|
+
modified_model = model
|
|
131
|
+
|
|
132
|
+
if "custom" in modified_model:
|
|
133
|
+
modified_model = modified_model.replace(
|
|
134
|
+
f"{provider_slug}/custom/", "openai/"
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
if provider_slug:
|
|
138
|
+
modified_model = modified_model.replace(f"{provider_slug}/", "")
|
|
125
139
|
|
|
126
|
-
return
|
|
140
|
+
return modified_model
|
|
127
141
|
|
|
128
142
|
@staticmethod
|
|
129
143
|
def get_provider_settings(model: str) -> Optional[Dict]:
|
|
@@ -137,6 +151,8 @@ class SecretsManager:
|
|
|
137
151
|
Dict: A dictionary containing all parameters needed for litellm.completion
|
|
138
152
|
"""
|
|
139
153
|
|
|
154
|
+
request_provider_model = model
|
|
155
|
+
|
|
140
156
|
# STEP 1: get vault secrets from route context and transform it
|
|
141
157
|
secrets = SecretsManager.get_from_route()
|
|
142
158
|
if not secrets:
|
|
@@ -146,11 +162,11 @@ class SecretsManager:
|
|
|
146
162
|
secrets = SecretsManager._parse_secrets(secrets=secrets)
|
|
147
163
|
|
|
148
164
|
# STEP 2: check model exists in supported standard models
|
|
149
|
-
provider = _standard_providers.get(
|
|
165
|
+
provider = _standard_providers.get(request_provider_model)
|
|
150
166
|
if not provider:
|
|
151
167
|
# check and get provider kind if model exists in custom provider models
|
|
152
168
|
provider = SecretsManager._custom_providers_get(
|
|
153
|
-
model=
|
|
169
|
+
model=request_provider_model,
|
|
154
170
|
secrets=secrets,
|
|
155
171
|
)
|
|
156
172
|
|
|
@@ -159,16 +175,19 @@ class SecretsManager:
|
|
|
159
175
|
return None
|
|
160
176
|
|
|
161
177
|
# STEP 2c: get litellm compatible model
|
|
162
|
-
|
|
163
|
-
|
|
178
|
+
request_provider_slug = (
|
|
179
|
+
SecretsManager._custom_provider_slug_get(
|
|
180
|
+
model=request_provider_model, secrets=secrets
|
|
181
|
+
)
|
|
182
|
+
or ""
|
|
164
183
|
)
|
|
165
|
-
|
|
166
|
-
model=
|
|
184
|
+
compatible_provider_model = SecretsManager._get_compatible_model(
|
|
185
|
+
model=request_provider_model, provider_slug=request_provider_slug
|
|
167
186
|
)
|
|
168
187
|
|
|
169
188
|
# STEP 3: initialize provider settings and simplify provider name
|
|
170
|
-
provider_settings =
|
|
171
|
-
|
|
189
|
+
provider_settings = dict(model=compatible_provider_model)
|
|
190
|
+
request_provider_kind = re.sub(
|
|
172
191
|
r"[\s-]+", "", provider.lower()
|
|
173
192
|
) # normalizing other special characters too (azure-openai)
|
|
174
193
|
|
|
@@ -180,23 +199,141 @@ class SecretsManager:
|
|
|
180
199
|
# i). Extract API key if present
|
|
181
200
|
# (for standard models -- openai/anthropic/gemini, etc)
|
|
182
201
|
if secret.get("kind") == "provider_key":
|
|
183
|
-
|
|
202
|
+
secret_provider_kind = secret_data.get("kind", "")
|
|
184
203
|
|
|
185
|
-
if
|
|
204
|
+
if request_provider_kind == secret_provider_kind:
|
|
186
205
|
if "key" in provider_info:
|
|
187
206
|
provider_settings["api_key"] = provider_info["key"]
|
|
188
207
|
continue
|
|
189
208
|
|
|
190
209
|
# ii). Extract Credentials if present
|
|
191
|
-
# (for custom providers -- aws bedrock/sagemaker,
|
|
210
|
+
# (for custom providers -- aws bedrock/sagemaker, vertex_ai, etc)
|
|
192
211
|
elif secret.get("kind") == "custom_provider":
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
212
|
+
secret_provider_kind = (
|
|
213
|
+
provider_info.get("kind", "").lower().replace(" ", "")
|
|
214
|
+
)
|
|
215
|
+
secret_provider_slug = secret_data.get("provider_slug", "")
|
|
216
|
+
secret_provider_models = secret_data.get("models", "")
|
|
217
|
+
secret_provider_extras = provider_info.get("extras", {})
|
|
218
|
+
|
|
219
|
+
if (
|
|
220
|
+
request_provider_kind == secret_provider_kind
|
|
221
|
+
and request_provider_slug == secret_provider_slug
|
|
222
|
+
and request_provider_model in secret_provider_models
|
|
223
|
+
):
|
|
224
|
+
if secret_provider_extras:
|
|
225
|
+
provider_settings.update(secret_provider_extras)
|
|
226
|
+
continue
|
|
227
|
+
|
|
228
|
+
if len(provider_settings.keys()) <= 1:
|
|
229
|
+
return None
|
|
230
|
+
|
|
231
|
+
return provider_settings
|
|
232
|
+
|
|
233
|
+
@staticmethod
|
|
234
|
+
async def retrieve_secrets():
|
|
235
|
+
return await get_secrets(
|
|
236
|
+
f"{ag.DEFAULT_AGENTA_SINGLETON_INSTANCE.host}/api",
|
|
237
|
+
RunningContext.get().credentials,
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
@staticmethod
|
|
241
|
+
async def ensure_secrets_in_workflow():
|
|
242
|
+
ctx = RunningContext.get()
|
|
243
|
+
|
|
244
|
+
ctx.secrets = await SecretsManager.retrieve_secrets()
|
|
245
|
+
|
|
246
|
+
RunningContext.set(ctx)
|
|
247
|
+
|
|
248
|
+
return ctx.secrets
|
|
249
|
+
|
|
250
|
+
@staticmethod
|
|
251
|
+
def get_provider_settings_from_workflow(model: str) -> Optional[Dict]:
|
|
252
|
+
"""
|
|
253
|
+
Builds the LLM request with appropriate kwargs based on the custom provider/model
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
model (str): The name of the model
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
Dict: A dictionary containing all parameters needed for litellm.completion
|
|
260
|
+
"""
|
|
261
|
+
|
|
262
|
+
request_provider_model = model
|
|
263
|
+
|
|
264
|
+
# STEP 1: get vault secrets from route context and transform it
|
|
265
|
+
secrets = RunningContext.get().secrets
|
|
266
|
+
if not secrets:
|
|
267
|
+
return None
|
|
268
|
+
|
|
269
|
+
# STEP 1b: Parse secrets into usable format
|
|
270
|
+
secrets = SecretsManager._parse_secrets(secrets=secrets)
|
|
271
|
+
|
|
272
|
+
# STEP 2: check model exists in supported standard models
|
|
273
|
+
provider = _standard_providers.get(request_provider_model)
|
|
274
|
+
if not provider:
|
|
275
|
+
# check and get provider kind if model exists in custom provider models
|
|
276
|
+
provider = SecretsManager._custom_providers_get(
|
|
277
|
+
model=request_provider_model,
|
|
278
|
+
secrets=secrets,
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
# STEP 2b: return None in the case provider is None
|
|
282
|
+
if not provider:
|
|
283
|
+
return None
|
|
284
|
+
|
|
285
|
+
# STEP 2c: get litellm compatible model
|
|
286
|
+
request_provider_slug = (
|
|
287
|
+
SecretsManager._custom_provider_slug_get(
|
|
288
|
+
model=request_provider_model, secrets=secrets
|
|
289
|
+
)
|
|
290
|
+
or ""
|
|
291
|
+
)
|
|
292
|
+
compatible_provider_model = SecretsManager._get_compatible_model(
|
|
293
|
+
model=request_provider_model, provider_slug=request_provider_slug
|
|
294
|
+
)
|
|
196
295
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
296
|
+
# STEP 3: initialize provider settings and simplify provider name
|
|
297
|
+
provider_settings = dict(model=compatible_provider_model)
|
|
298
|
+
request_provider_kind = re.sub(
|
|
299
|
+
r"[\s-]+", "", provider.lower()
|
|
300
|
+
) # normalizing other special characters too (azure-openai)
|
|
301
|
+
|
|
302
|
+
# STEP 4: get credentials for model
|
|
303
|
+
for secret in secrets:
|
|
304
|
+
secret_data = secret.get("data", {})
|
|
305
|
+
provider_info = secret_data.get("provider", {})
|
|
306
|
+
|
|
307
|
+
# i). Extract API key if present
|
|
308
|
+
# (for standard models -- openai/anthropic/gemini, etc)
|
|
309
|
+
if secret.get("kind") == "provider_key":
|
|
310
|
+
secret_provider_kind = secret_data.get("kind", "")
|
|
311
|
+
|
|
312
|
+
if request_provider_kind == secret_provider_kind:
|
|
313
|
+
if "key" in provider_info:
|
|
314
|
+
provider_settings["api_key"] = provider_info["key"]
|
|
200
315
|
continue
|
|
201
316
|
|
|
317
|
+
# ii). Extract Credentials if present
|
|
318
|
+
# (for custom providers -- aws bedrock/sagemaker, vertex_ai, etc)
|
|
319
|
+
elif secret.get("kind") == "custom_provider":
|
|
320
|
+
secret_provider_kind = (
|
|
321
|
+
provider_info.get("kind", "").lower().replace(" ", "")
|
|
322
|
+
)
|
|
323
|
+
secret_provider_slug = secret_data.get("provider_slug", "")
|
|
324
|
+
secret_provider_models = secret_data.get("models", "")
|
|
325
|
+
secret_provider_extras = provider_info.get("extras", {})
|
|
326
|
+
|
|
327
|
+
if (
|
|
328
|
+
request_provider_kind == secret_provider_kind
|
|
329
|
+
and request_provider_slug == secret_provider_slug
|
|
330
|
+
and request_provider_model in secret_provider_models
|
|
331
|
+
):
|
|
332
|
+
if secret_provider_extras:
|
|
333
|
+
provider_settings.update(secret_provider_extras)
|
|
334
|
+
continue
|
|
335
|
+
|
|
336
|
+
if len(provider_settings.keys()) <= 1:
|
|
337
|
+
return None
|
|
338
|
+
|
|
202
339
|
return provider_settings
|
agenta/sdk/managers/shared.py
CHANGED
|
@@ -478,7 +478,9 @@ class SharedManager:
|
|
|
478
478
|
config=ConfigRequest(
|
|
479
479
|
params=parameters,
|
|
480
480
|
variant_ref=variant_ref.model_dump() if variant_ref else None, # type: ignore
|
|
481
|
-
application_ref=application_ref.model_dump()
|
|
481
|
+
application_ref=application_ref.model_dump()
|
|
482
|
+
if application_ref
|
|
483
|
+
else None, # type: ignore
|
|
482
484
|
)
|
|
483
485
|
)
|
|
484
486
|
|