agenta 0.32.0a1__py3-none-any.whl → 0.33.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agenta/__init__.py +2 -0
- agenta/client/backend/__init__.py +39 -31
- agenta/client/backend/admin/__init__.py +1 -0
- agenta/client/backend/admin/client.py +576 -0
- agenta/client/backend/apps/client.py +450 -68
- agenta/client/backend/bases/client.py +10 -10
- agenta/client/backend/client.py +112 -122
- agenta/client/backend/containers/client.py +70 -28
- agenta/client/backend/core/http_client.py +3 -3
- agenta/client/backend/environments/client.py +8 -8
- agenta/client/backend/evaluations/client.py +46 -52
- agenta/client/backend/evaluators/client.py +32 -32
- agenta/client/backend/human_evaluations/__init__.py +1 -0
- agenta/client/backend/human_evaluations/client.py +1692 -0
- agenta/client/backend/observability/__init__.py +4 -0
- agenta/client/backend/observability/client.py +221 -744
- agenta/client/backend/testsets/client.py +38 -202
- agenta/client/backend/types/__init__.py +34 -28
- agenta/client/backend/types/account_response.py +24 -0
- agenta/client/backend/types/app_variant_revision.py +2 -1
- agenta/client/backend/types/{create_trace_response.py → delete_evaluation.py} +2 -3
- agenta/client/backend/types/{evaluation_scenario_score_update.py → legacy_scope_request.py} +2 -2
- agenta/client/backend/types/legacy_scopes_response.py +29 -0
- agenta/client/backend/types/{human_evaluation_update.py → legacy_user_request.py} +4 -4
- agenta/client/backend/types/{span_variant.py → legacy_user_response.py} +2 -4
- agenta/client/backend/types/organization_membership_request.py +25 -0
- agenta/client/backend/types/organization_request.py +23 -0
- agenta/client/backend/types/permission.py +4 -0
- agenta/client/backend/types/{llm_tokens.py → project_membership_request.py} +8 -5
- agenta/client/backend/types/project_request.py +26 -0
- agenta/client/backend/types/project_scope.py +29 -0
- agenta/client/backend/types/provider_kind.py +1 -1
- agenta/client/backend/types/reference.py +22 -0
- agenta/client/backend/types/role.py +15 -0
- agenta/client/backend/types/scopes_response_model.py +22 -0
- agenta/client/backend/types/score.py +1 -1
- agenta/client/backend/types/secret_response_dto.py +2 -2
- agenta/client/backend/types/user_request.py +22 -0
- agenta/client/backend/types/workspace_membership_request.py +26 -0
- agenta/client/backend/types/workspace_request.py +25 -0
- agenta/client/backend/variants/client.py +208 -42
- agenta/client/backend/vault/client.py +11 -9
- agenta/sdk/__init__.py +3 -0
- agenta/sdk/agenta_init.py +3 -1
- agenta/sdk/assets.py +4 -4
- agenta/sdk/decorators/routing.py +129 -23
- agenta/sdk/decorators/tracing.py +16 -4
- agenta/sdk/litellm/litellm.py +44 -8
- agenta/sdk/litellm/mockllm.py +2 -2
- agenta/sdk/litellm/mocks/__init__.py +9 -3
- agenta/sdk/managers/apps.py +64 -0
- agenta/sdk/managers/shared.py +2 -2
- agenta/sdk/middleware/auth.py +156 -53
- agenta/sdk/middleware/config.py +28 -16
- agenta/sdk/middleware/inline.py +1 -1
- agenta/sdk/middleware/mock.py +1 -1
- agenta/sdk/middleware/otel.py +1 -1
- agenta/sdk/middleware/vault.py +1 -1
- agenta/sdk/tracing/exporters.py +0 -1
- agenta/sdk/tracing/inline.py +26 -30
- agenta/sdk/types.py +12 -9
- {agenta-0.32.0a1.dist-info → agenta-0.33.0.dist-info}/METADATA +23 -20
- {agenta-0.32.0a1.dist-info → agenta-0.33.0.dist-info}/RECORD +69 -63
- agenta/client/backend/observability_v_1/__init__.py +0 -5
- agenta/client/backend/observability_v_1/client.py +0 -763
- agenta/client/backend/types/create_span.py +0 -45
- agenta/client/backend/types/human_evaluation_scenario_update.py +0 -30
- agenta/client/backend/types/new_human_evaluation.py +0 -27
- agenta/client/backend/types/outputs.py +0 -5
- agenta/client/backend/types/span.py +0 -42
- agenta/client/backend/types/span_detail.py +0 -44
- agenta/client/backend/types/span_status_code.py +0 -5
- agenta/client/backend/types/trace_detail.py +0 -44
- agenta/client/backend/types/with_pagination.py +0 -26
- /agenta/client/backend/{observability_v_1 → observability}/types/__init__.py +0 -0
- /agenta/client/backend/{observability_v_1 → observability}/types/format.py +0 -0
- /agenta/client/backend/{observability_v_1 → observability}/types/query_analytics_response.py +0 -0
- /agenta/client/backend/{observability_v_1 → observability}/types/query_traces_response.py +0 -0
- {agenta-0.32.0a1.dist-info → agenta-0.33.0.dist-info}/WHEEL +0 -0
- {agenta-0.32.0a1.dist-info → agenta-0.33.0.dist-info}/entry_points.txt +0 -0
agenta/sdk/decorators/routing.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from sre_parse import NOT_LITERAL_UNI_IGNORE
|
|
2
1
|
from typing import Type, Any, Callable, Dict, Optional, Tuple, List
|
|
3
2
|
from inspect import signature, iscoroutinefunction, Signature, Parameter
|
|
4
3
|
from functools import wraps
|
|
@@ -6,6 +5,7 @@ from traceback import format_exception
|
|
|
6
5
|
from asyncio import sleep
|
|
7
6
|
from uuid import UUID
|
|
8
7
|
from pydantic import BaseModel, HttpUrl, ValidationError
|
|
8
|
+
from os import environ
|
|
9
9
|
|
|
10
10
|
from fastapi import Body, FastAPI, HTTPException, Request
|
|
11
11
|
|
|
@@ -38,12 +38,18 @@ from agenta.sdk.types import (
|
|
|
38
38
|
|
|
39
39
|
import agenta as ag
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
app = FastAPI()
|
|
43
41
|
log.setLevel("DEBUG")
|
|
44
42
|
|
|
43
|
+
AGENTA_RUNTIME_PREFIX = environ.get("AGENTA_RUNTIME_PREFIX", "")
|
|
44
|
+
|
|
45
|
+
app = FastAPI(
|
|
46
|
+
docs_url=f"{AGENTA_RUNTIME_PREFIX}/docs", # Swagger UI
|
|
47
|
+
openapi_url=f"{AGENTA_RUNTIME_PREFIX}/openapi.json", # OpenAPI schema
|
|
48
|
+
)
|
|
45
49
|
|
|
46
|
-
app.include_router(router, prefix=
|
|
50
|
+
app.include_router(router, prefix=AGENTA_RUNTIME_PREFIX)
|
|
51
|
+
|
|
52
|
+
log.error("Agenta - Runtime Prefix:" + AGENTA_RUNTIME_PREFIX)
|
|
47
53
|
|
|
48
54
|
|
|
49
55
|
class PathValidator(BaseModel):
|
|
@@ -114,13 +120,13 @@ class entrypoint:
|
|
|
114
120
|
routes = list()
|
|
115
121
|
|
|
116
122
|
_middleware = False
|
|
117
|
-
_run_path = "/run"
|
|
118
|
-
_test_path = "/test"
|
|
123
|
+
_run_path = f"{AGENTA_RUNTIME_PREFIX}/run"
|
|
124
|
+
_test_path = f"{AGENTA_RUNTIME_PREFIX}/test"
|
|
119
125
|
_config_key = "ag_config"
|
|
120
126
|
# LEGACY
|
|
121
|
-
_legacy_playground_run_path = "/playground/run"
|
|
122
|
-
_legacy_generate_path = "/generate"
|
|
123
|
-
_legacy_generate_deployed_path = "/generate_deployed"
|
|
127
|
+
_legacy_playground_run_path = f"{AGENTA_RUNTIME_PREFIX}/playground/run"
|
|
128
|
+
_legacy_generate_path = f"{AGENTA_RUNTIME_PREFIX}/generate"
|
|
129
|
+
_legacy_generate_deployed_path = f"{AGENTA_RUNTIME_PREFIX}/generate_deployed"
|
|
124
130
|
|
|
125
131
|
def __init__(
|
|
126
132
|
self,
|
|
@@ -142,8 +148,8 @@ class entrypoint:
|
|
|
142
148
|
app.add_middleware(InlineMiddleware)
|
|
143
149
|
app.add_middleware(VaultMiddleware)
|
|
144
150
|
app.add_middleware(ConfigMiddleware)
|
|
145
|
-
app.add_middleware(OTelMiddleware)
|
|
146
151
|
app.add_middleware(AuthMiddleware)
|
|
152
|
+
app.add_middleware(OTelMiddleware)
|
|
147
153
|
app.add_middleware(CORSMiddleware)
|
|
148
154
|
### ------------------ #
|
|
149
155
|
|
|
@@ -175,14 +181,22 @@ class entrypoint:
|
|
|
175
181
|
self.update_run_wrapper_signature(wrapper=run_wrapper)
|
|
176
182
|
|
|
177
183
|
run_route = f"{entrypoint._run_path}{route_path}"
|
|
178
|
-
app.post(
|
|
184
|
+
app.post(
|
|
185
|
+
run_route,
|
|
186
|
+
response_model=BaseResponse,
|
|
187
|
+
response_model_exclude_none=True,
|
|
188
|
+
)(run_wrapper)
|
|
179
189
|
|
|
180
190
|
# LEGACY
|
|
181
191
|
# TODO: Removing this implies breaking changes in :
|
|
182
192
|
# - calls to /generate_deployed must be replaced with calls to /run
|
|
183
193
|
if route_path == "":
|
|
184
194
|
run_route = entrypoint._legacy_generate_deployed_path
|
|
185
|
-
app.post(
|
|
195
|
+
app.post(
|
|
196
|
+
run_route,
|
|
197
|
+
response_model=BaseResponse,
|
|
198
|
+
response_model_exclude_none=True,
|
|
199
|
+
)(run_wrapper)
|
|
186
200
|
# LEGACY
|
|
187
201
|
### ----------- #
|
|
188
202
|
|
|
@@ -203,21 +217,33 @@ class entrypoint:
|
|
|
203
217
|
self.update_test_wrapper_signature(wrapper=test_wrapper, config_instance=config)
|
|
204
218
|
|
|
205
219
|
test_route = f"{entrypoint._test_path}{route_path}"
|
|
206
|
-
app.post(
|
|
220
|
+
app.post(
|
|
221
|
+
test_route,
|
|
222
|
+
response_model=BaseResponse,
|
|
223
|
+
response_model_exclude_none=True,
|
|
224
|
+
)(test_wrapper)
|
|
207
225
|
|
|
208
226
|
# LEGACY
|
|
209
227
|
# TODO: Removing this implies breaking changes in :
|
|
210
228
|
# - calls to /generate must be replaced with calls to /test
|
|
211
229
|
if route_path == "":
|
|
212
230
|
test_route = entrypoint._legacy_generate_path
|
|
213
|
-
app.post(
|
|
231
|
+
app.post(
|
|
232
|
+
test_route,
|
|
233
|
+
response_model=BaseResponse,
|
|
234
|
+
response_model_exclude_none=True,
|
|
235
|
+
)(test_wrapper)
|
|
214
236
|
# LEGACY
|
|
215
237
|
|
|
216
238
|
# LEGACY
|
|
217
239
|
# TODO: Removing this implies no breaking changes
|
|
218
240
|
if route_path == "":
|
|
219
241
|
test_route = entrypoint._legacy_playground_run_path
|
|
220
|
-
app.post(
|
|
242
|
+
app.post(
|
|
243
|
+
test_route,
|
|
244
|
+
response_model=BaseResponse,
|
|
245
|
+
response_model_exclude_none=True,
|
|
246
|
+
)(test_wrapper)
|
|
221
247
|
# LEGACY
|
|
222
248
|
### ------------ #
|
|
223
249
|
|
|
@@ -249,17 +275,18 @@ class entrypoint:
|
|
|
249
275
|
)
|
|
250
276
|
# LEGACY
|
|
251
277
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
openapi_schema["agenta_sdk"] = {"version": get_current_version()}
|
|
278
|
+
openapi_schema = self.openapi()
|
|
279
|
+
|
|
255
280
|
for _route in entrypoint.routes:
|
|
256
281
|
if _route["config"] is not None:
|
|
257
282
|
self.override_config_in_schema(
|
|
258
283
|
openapi_schema=openapi_schema,
|
|
259
284
|
func_name=_route["func"],
|
|
260
|
-
endpoint=_route["endpoint"],
|
|
285
|
+
endpoint=_route["endpoint"].replace(AGENTA_RUNTIME_PREFIX, ""),
|
|
261
286
|
config=_route["config"],
|
|
262
287
|
)
|
|
288
|
+
|
|
289
|
+
app.openapi_schema = openapi_schema
|
|
263
290
|
### --------------- #
|
|
264
291
|
|
|
265
292
|
def parse_config(self) -> Tuple[Optional[Type[BaseModel]], Dict[str, Any]]:
|
|
@@ -369,7 +396,9 @@ class entrypoint:
|
|
|
369
396
|
):
|
|
370
397
|
display_exception("Application Exception")
|
|
371
398
|
|
|
372
|
-
status_code =
|
|
399
|
+
status_code = (
|
|
400
|
+
getattr(error, "status_code") if hasattr(error, "status_code") else 500
|
|
401
|
+
)
|
|
373
402
|
stacktrace = format_exception(error, value=error, tb=error.__traceback__) # type: ignore
|
|
374
403
|
|
|
375
404
|
raise HTTPException(
|
|
@@ -430,8 +459,8 @@ class entrypoint:
|
|
|
430
459
|
link = context.link
|
|
431
460
|
|
|
432
461
|
tree = None
|
|
433
|
-
_tree_id = link.get("tree_id") if link else None
|
|
434
|
-
tree_id = str(UUID(int=_tree_id)) if _tree_id else None
|
|
462
|
+
_tree_id = link.get("tree_id") if link else None # in int format
|
|
463
|
+
tree_id = str(UUID(int=_tree_id)) if _tree_id else None # in uuid_as_str format
|
|
435
464
|
|
|
436
465
|
if _tree_id is not None:
|
|
437
466
|
if inline:
|
|
@@ -544,6 +573,82 @@ class entrypoint:
|
|
|
544
573
|
)
|
|
545
574
|
)
|
|
546
575
|
|
|
576
|
+
def openapi(self):
|
|
577
|
+
app.openapi_schema = None # Forces FastAPI to re-generate the schema
|
|
578
|
+
|
|
579
|
+
openapi_schema = app.openapi()
|
|
580
|
+
|
|
581
|
+
# ✅ Fix paths by removing the prefix
|
|
582
|
+
updated_paths = {}
|
|
583
|
+
for path, methods in openapi_schema["paths"].items():
|
|
584
|
+
new_path = (
|
|
585
|
+
path[len(AGENTA_RUNTIME_PREFIX) :]
|
|
586
|
+
if path.startswith(AGENTA_RUNTIME_PREFIX)
|
|
587
|
+
else path
|
|
588
|
+
)
|
|
589
|
+
updated_paths[new_path] = methods
|
|
590
|
+
openapi_schema["paths"] = updated_paths # Replace paths
|
|
591
|
+
|
|
592
|
+
# ✅ Fix schema names and update `$ref` references
|
|
593
|
+
if "components" in openapi_schema and "schemas" in openapi_schema["components"]:
|
|
594
|
+
updated_schemas = {}
|
|
595
|
+
schema_name_map = {} # Map old schema names to new schema names
|
|
596
|
+
|
|
597
|
+
for schema_name, schema_value in openapi_schema["components"][
|
|
598
|
+
"schemas"
|
|
599
|
+
].items():
|
|
600
|
+
if AGENTA_RUNTIME_PREFIX and AGENTA_RUNTIME_PREFIX != "":
|
|
601
|
+
new_schema_name = schema_name.replace(
|
|
602
|
+
AGENTA_RUNTIME_PREFIX.lstrip("/").replace("/", "_") + "_", ""
|
|
603
|
+
).strip("_")
|
|
604
|
+
else:
|
|
605
|
+
new_schema_name = schema_name
|
|
606
|
+
updated_schemas[new_schema_name] = schema_value
|
|
607
|
+
schema_name_map[schema_name] = new_schema_name # Store mapping
|
|
608
|
+
|
|
609
|
+
# ✅ Fix `$ref` references
|
|
610
|
+
for path, methods in updated_paths.items():
|
|
611
|
+
for method in methods.values():
|
|
612
|
+
if "requestBody" in method and "content" in method["requestBody"]:
|
|
613
|
+
for content_type, content in method["requestBody"][
|
|
614
|
+
"content"
|
|
615
|
+
].items():
|
|
616
|
+
if "$ref" in content["schema"]:
|
|
617
|
+
old_ref = content["schema"]["$ref"]
|
|
618
|
+
schema_name = old_ref.split("/")[
|
|
619
|
+
-1
|
|
620
|
+
] # Extract schema name
|
|
621
|
+
if schema_name in schema_name_map:
|
|
622
|
+
content["schema"][
|
|
623
|
+
"$ref"
|
|
624
|
+
] = f"#/components/schemas/{schema_name_map[schema_name]}"
|
|
625
|
+
|
|
626
|
+
if "responses" in method:
|
|
627
|
+
for status_code, response in method["responses"].items():
|
|
628
|
+
if "content" in response:
|
|
629
|
+
for content_type, content in response[
|
|
630
|
+
"content"
|
|
631
|
+
].items():
|
|
632
|
+
if "$ref" in content["schema"]:
|
|
633
|
+
old_ref = content["schema"]["$ref"]
|
|
634
|
+
schema_name = old_ref.split("/")[
|
|
635
|
+
-1
|
|
636
|
+
] # Extract schema name
|
|
637
|
+
if schema_name in schema_name_map:
|
|
638
|
+
content["schema"][
|
|
639
|
+
"$ref"
|
|
640
|
+
] = f"#/components/schemas/{schema_name_map[schema_name]}"
|
|
641
|
+
|
|
642
|
+
# ✅ Update OpenAPI schema with fixed schemas
|
|
643
|
+
openapi_schema["components"]["schemas"] = updated_schemas
|
|
644
|
+
|
|
645
|
+
# ✅ Add Agenta SDK version info
|
|
646
|
+
openapi_schema["agenta_sdk"] = {"version": get_current_version()}
|
|
647
|
+
|
|
648
|
+
print(openapi_schema)
|
|
649
|
+
|
|
650
|
+
return openapi_schema
|
|
651
|
+
|
|
547
652
|
def override_config_in_schema(
|
|
548
653
|
self,
|
|
549
654
|
openapi_schema: dict,
|
|
@@ -553,6 +658,7 @@ class entrypoint:
|
|
|
553
658
|
):
|
|
554
659
|
"""Override config in OpenAPI schema to add agenta-specific metadata."""
|
|
555
660
|
endpoint = endpoint[1:].replace("/", "_")
|
|
661
|
+
|
|
556
662
|
schema_key = f"Body_{func_name}_{endpoint}_post"
|
|
557
663
|
schema_to_override = openapi_schema["components"]["schemas"][schema_key]
|
|
558
664
|
|
|
@@ -560,7 +666,7 @@ class entrypoint:
|
|
|
560
666
|
config_class_name = type(config).__name__
|
|
561
667
|
config_schema = openapi_schema["components"]["schemas"][config_class_name]
|
|
562
668
|
# Process each field in the config class
|
|
563
|
-
for field_name, field in config.__class__.
|
|
669
|
+
for field_name, field in config.__class__.model_fields.items():
|
|
564
670
|
# Check if field has Annotated metadata for MultipleChoice
|
|
565
671
|
if hasattr(field, "metadata") and field.metadata:
|
|
566
672
|
for meta in field.metadata:
|
agenta/sdk/decorators/tracing.py
CHANGED
|
@@ -165,15 +165,27 @@ class instrument: # pylint: disable=invalid-name
|
|
|
165
165
|
usage = {"total_tokens": usage}
|
|
166
166
|
|
|
167
167
|
span.set_attributes(
|
|
168
|
-
attributes={"total": cost},
|
|
168
|
+
attributes={"total": float(cost) if cost else None},
|
|
169
169
|
namespace="metrics.unit.costs",
|
|
170
170
|
)
|
|
171
171
|
span.set_attributes(
|
|
172
172
|
attributes=(
|
|
173
173
|
{
|
|
174
|
-
"prompt":
|
|
175
|
-
|
|
176
|
-
|
|
174
|
+
"prompt": (
|
|
175
|
+
float(usage.get("prompt_tokens"))
|
|
176
|
+
if usage.get("prompt_tokens", None)
|
|
177
|
+
else None
|
|
178
|
+
),
|
|
179
|
+
"completion": (
|
|
180
|
+
float(usage.get("completion_tokens"))
|
|
181
|
+
if usage.get("completion_tokens", None)
|
|
182
|
+
else None
|
|
183
|
+
),
|
|
184
|
+
"total": (
|
|
185
|
+
float(usage.get("total_tokens", None))
|
|
186
|
+
if usage.get("total_tokens", None)
|
|
187
|
+
else None
|
|
188
|
+
),
|
|
177
189
|
}
|
|
178
190
|
),
|
|
179
191
|
namespace="metrics.unit.tokens",
|
agenta/sdk/litellm/litellm.py
CHANGED
|
@@ -154,16 +154,34 @@ def litellm_handler():
|
|
|
154
154
|
pass
|
|
155
155
|
|
|
156
156
|
span.set_attributes(
|
|
157
|
-
attributes={
|
|
157
|
+
attributes={
|
|
158
|
+
"total": (
|
|
159
|
+
float(kwargs.get("response_cost"))
|
|
160
|
+
if kwargs.get("response_cost")
|
|
161
|
+
else None
|
|
162
|
+
)
|
|
163
|
+
},
|
|
158
164
|
namespace="metrics.unit.costs",
|
|
159
165
|
)
|
|
160
166
|
|
|
161
167
|
span.set_attributes(
|
|
162
168
|
attributes=(
|
|
163
169
|
{
|
|
164
|
-
"prompt":
|
|
165
|
-
|
|
166
|
-
|
|
170
|
+
"prompt": (
|
|
171
|
+
float(response_obj.usage.prompt_tokens)
|
|
172
|
+
if response_obj.usage.prompt_tokens
|
|
173
|
+
else None
|
|
174
|
+
),
|
|
175
|
+
"completion": (
|
|
176
|
+
float(response_obj.usage.completion_tokens)
|
|
177
|
+
if response_obj.usage.completion_tokens
|
|
178
|
+
else None
|
|
179
|
+
),
|
|
180
|
+
"total": (
|
|
181
|
+
float(response_obj.usage.total_tokens)
|
|
182
|
+
if response_obj.usage.total_tokens
|
|
183
|
+
else None
|
|
184
|
+
),
|
|
167
185
|
}
|
|
168
186
|
),
|
|
169
187
|
namespace="metrics.unit.tokens",
|
|
@@ -264,16 +282,34 @@ def litellm_handler():
|
|
|
264
282
|
pass
|
|
265
283
|
|
|
266
284
|
span.set_attributes(
|
|
267
|
-
attributes={
|
|
285
|
+
attributes={
|
|
286
|
+
"total": (
|
|
287
|
+
float(kwargs.get("response_cost"))
|
|
288
|
+
if kwargs.get("response_cost")
|
|
289
|
+
else None
|
|
290
|
+
)
|
|
291
|
+
},
|
|
268
292
|
namespace="metrics.unit.costs",
|
|
269
293
|
)
|
|
270
294
|
|
|
271
295
|
span.set_attributes(
|
|
272
296
|
attributes=(
|
|
273
297
|
{
|
|
274
|
-
"prompt":
|
|
275
|
-
|
|
276
|
-
|
|
298
|
+
"prompt": (
|
|
299
|
+
float(response_obj.usage.prompt_tokens)
|
|
300
|
+
if response_obj.usage.prompt_tokens
|
|
301
|
+
else None
|
|
302
|
+
),
|
|
303
|
+
"completion": (
|
|
304
|
+
float(response_obj.usage.completion_tokens)
|
|
305
|
+
if response_obj.usage.completion_tokens
|
|
306
|
+
else None
|
|
307
|
+
),
|
|
308
|
+
"total": (
|
|
309
|
+
float(response_obj.usage.total_tokens)
|
|
310
|
+
if response_obj.usage.total_tokens
|
|
311
|
+
else None
|
|
312
|
+
),
|
|
277
313
|
}
|
|
278
314
|
),
|
|
279
315
|
namespace="metrics.unit.tokens",
|
agenta/sdk/litellm/mockllm.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Optional, Protocol, Any
|
|
2
2
|
|
|
3
|
-
from agenta.sdk.context.routing import routing_context
|
|
4
3
|
from agenta.sdk.litellm.mocks import MOCKS
|
|
4
|
+
from agenta.sdk.context.routing import routing_context
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class LitellmProtocol(Protocol):
|
|
@@ -19,7 +19,7 @@ async def acompletion(*args, **kwargs):
|
|
|
19
19
|
if mock not in MOCKS:
|
|
20
20
|
raise ValueError(f"Mock {mock} not found")
|
|
21
21
|
|
|
22
|
-
return MOCKS[mock]
|
|
22
|
+
return MOCKS[mock](*args, **kwargs)
|
|
23
23
|
|
|
24
24
|
if not litellm:
|
|
25
25
|
raise ValueError("litellm not found")
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
|
|
1
3
|
from pydantic import BaseModel
|
|
2
4
|
|
|
3
5
|
|
|
@@ -13,8 +15,8 @@ class MockResponseModel(BaseModel):
|
|
|
13
15
|
choices: list[MockChoiceModel]
|
|
14
16
|
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
def hello_mock_response(*args, **kwargs) -> MockResponseModel:
|
|
19
|
+
return MockResponseModel(
|
|
18
20
|
choices=[
|
|
19
21
|
MockChoiceModel(
|
|
20
22
|
message=MockMessageModel(
|
|
@@ -22,5 +24,9 @@ MOCKS = {
|
|
|
22
24
|
)
|
|
23
25
|
)
|
|
24
26
|
],
|
|
25
|
-
)
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
MOCKS: dict[str, Callable[..., MockResponseModel]] = {
|
|
31
|
+
"hello": hello_mock_response,
|
|
26
32
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from agenta.sdk.utils.exceptions import handle_exceptions
|
|
4
|
+
|
|
5
|
+
import agenta as ag
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AppManager:
|
|
12
|
+
@classmethod
|
|
13
|
+
@handle_exceptions()
|
|
14
|
+
def create(cls, *, app_slug: str, template_key: str):
|
|
15
|
+
app_response = ag.api.apps.create_app(
|
|
16
|
+
app_name=app_slug, template_key=template_key
|
|
17
|
+
)
|
|
18
|
+
return app_response
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
@handle_exceptions()
|
|
22
|
+
async def acreate(cls, *, app_slug: str, template_key: str):
|
|
23
|
+
app_response = await ag.async_api.apps.create_app(
|
|
24
|
+
app_name=app_slug, template_key=template_key
|
|
25
|
+
)
|
|
26
|
+
return app_response
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
@handle_exceptions()
|
|
30
|
+
def list(cls):
|
|
31
|
+
apps_response = ag.api.apps.list_apps()
|
|
32
|
+
return apps_response
|
|
33
|
+
|
|
34
|
+
@classmethod
|
|
35
|
+
@handle_exceptions()
|
|
36
|
+
async def alist(cls):
|
|
37
|
+
apps_response = await ag.async_api.apps.list_apps()
|
|
38
|
+
return apps_response
|
|
39
|
+
|
|
40
|
+
@classmethod
|
|
41
|
+
@handle_exceptions()
|
|
42
|
+
def update(cls, *, app_id: str, app_slug: str):
|
|
43
|
+
app_response = ag.api.apps.update_app(app_id=app_id, app_name=app_slug)
|
|
44
|
+
return app_response
|
|
45
|
+
|
|
46
|
+
@classmethod
|
|
47
|
+
@handle_exceptions()
|
|
48
|
+
async def aupdate(cls, *, app_id: str, app_slug: str):
|
|
49
|
+
app_response = await ag.async_api.apps.update_app(
|
|
50
|
+
app_id=app_id, app_name=app_slug
|
|
51
|
+
)
|
|
52
|
+
return app_response
|
|
53
|
+
|
|
54
|
+
@classmethod
|
|
55
|
+
@handle_exceptions()
|
|
56
|
+
def delete(cls, *, app_id: str):
|
|
57
|
+
ag.api.apps.remove_app(app_id=app_id)
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
@handle_exceptions()
|
|
62
|
+
async def adelete(cls, *, app_id: str):
|
|
63
|
+
await ag.async_api.apps.remove_app(app_id=app_id)
|
|
64
|
+
return None
|
agenta/sdk/managers/shared.py
CHANGED
|
@@ -505,12 +505,12 @@ class SharedManager:
|
|
|
505
505
|
slug=variant_slug,
|
|
506
506
|
version=None,
|
|
507
507
|
id=None,
|
|
508
|
-
),
|
|
508
|
+
).model_dump(),
|
|
509
509
|
application_ref=SharedManager._ref_or_none( # type: ignore # type: ignore
|
|
510
510
|
slug=app_slug,
|
|
511
511
|
version=None,
|
|
512
512
|
id=app_id,
|
|
513
|
-
),
|
|
513
|
+
).model_dump(),
|
|
514
514
|
)
|
|
515
515
|
)
|
|
516
516
|
|