agenta 0.27.7a1__py3-none-any.whl → 0.27.8a2__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/client/backend/__init__.py +63 -0
- agenta/client/backend/client.py +22 -22
- agenta/client/backend/core/http_client.py +15 -7
- agenta/client/backend/evaluations/client.py +0 -11
- agenta/client/backend/observability/client.py +4 -4
- agenta/client/backend/observability_v_1/__init__.py +5 -0
- agenta/client/backend/observability_v_1/client.py +560 -0
- agenta/client/backend/observability_v_1/types/__init__.py +6 -0
- agenta/client/backend/observability_v_1/types/format.py +5 -0
- agenta/client/backend/observability_v_1/types/query_traces_response.py +11 -0
- agenta/client/backend/testsets/client.py +8 -40
- agenta/client/backend/types/__init__.py +58 -0
- 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/collect_status_response.py +22 -0
- agenta/client/backend/types/exception_dto.py +26 -0
- agenta/client/backend/types/link_dto.py +24 -0
- 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/parent_dto.py +21 -0
- agenta/client/backend/types/root_dto.py +21 -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/status_code.py +5 -0
- agenta/client/backend/types/status_dto.py +23 -0
- agenta/client/backend/types/time_dto.py +23 -0
- agenta/client/backend/types/tree_dto.py +23 -0
- agenta/client/backend/types/tree_type.py +5 -0
- agenta/client/backend/variants/client.py +24 -16
- agenta/sdk/__init__.py +2 -0
- agenta/sdk/agenta_init.py +4 -9
- agenta/sdk/decorators/routing.py +23 -41
- agenta/sdk/litellm/litellm.py +30 -75
- agenta/sdk/middleware/auth.py +5 -5
- agenta/sdk/tracing/context.py +6 -6
- agenta/sdk/tracing/inline.py +41 -147
- agenta/sdk/tracing/processors.py +1 -3
- agenta/sdk/tracing/tracing.py +1 -5
- agenta/sdk/types.py +5 -2
- agenta/sdk/utils/exceptions.py +15 -9
- agenta/sdk/utils/logging.py +5 -1
- {agenta-0.27.7a1.dist-info → agenta-0.27.8a2.dist-info}/METADATA +1 -1
- {agenta-0.27.7a1.dist-info → agenta-0.27.8a2.dist-info}/RECORD +58 -25
- agenta/sdk/utils/debug.py +0 -68
- {agenta-0.27.7a1.dist-info → agenta-0.27.8a2.dist-info}/WHEEL +0 -0
- {agenta-0.27.7a1.dist-info → agenta-0.27.8a2.dist-info}/entry_points.txt +0 -0
agenta/sdk/decorators/routing.py
CHANGED
|
@@ -143,9 +143,7 @@ class entrypoint:
|
|
|
143
143
|
_MIDDLEWARES = False
|
|
144
144
|
|
|
145
145
|
except: # pylint: disable=bare-except
|
|
146
|
-
log.
|
|
147
|
-
log.error("Agenta SDK - failed to secure route: %s", route_path)
|
|
148
|
-
log.error("------------------------------------")
|
|
146
|
+
log.warning("Agenta SDK - failed to secure route: %s", route_path)
|
|
149
147
|
### --- Update Middleware --- #
|
|
150
148
|
|
|
151
149
|
DEFAULT_PATH = "generate"
|
|
@@ -357,9 +355,7 @@ class entrypoint:
|
|
|
357
355
|
*args,
|
|
358
356
|
**func_params,
|
|
359
357
|
):
|
|
360
|
-
log.info("
|
|
361
|
-
log.info(f"Agenta SDK - running route: {repr(self.route_path or '/')}")
|
|
362
|
-
log.info("---------------------------")
|
|
358
|
+
log.info("Agenta SDK - handling route: %s", repr(self.route_path or "/"))
|
|
363
359
|
|
|
364
360
|
tracing_context.set(routing_context.get())
|
|
365
361
|
|
|
@@ -377,7 +373,7 @@ class entrypoint:
|
|
|
377
373
|
|
|
378
374
|
async def handle_success(self, result: Any, inline_trace: bool):
|
|
379
375
|
data = None
|
|
380
|
-
trace =
|
|
376
|
+
trace = None
|
|
381
377
|
|
|
382
378
|
with suppress():
|
|
383
379
|
data = self.patch_result(result)
|
|
@@ -389,24 +385,20 @@ class entrypoint:
|
|
|
389
385
|
log.info(f"Agenta SDK - exiting with success: 200")
|
|
390
386
|
log.info(f"----------------------------------")
|
|
391
387
|
|
|
392
|
-
return BaseResponse(data=data,
|
|
388
|
+
return BaseResponse(data=data, tree=trace)
|
|
393
389
|
|
|
394
390
|
def handle_failure(self, error: Exception):
|
|
395
|
-
log.
|
|
396
|
-
log.
|
|
397
|
-
log.
|
|
398
|
-
log.
|
|
399
|
-
log.
|
|
391
|
+
log.warning("--------------------------------------------------")
|
|
392
|
+
log.warning("Agenta SDK - handling application exception below:")
|
|
393
|
+
log.warning("--------------------------------------------------")
|
|
394
|
+
log.warning(format_exc().strip("\n"))
|
|
395
|
+
log.warning("--------------------------------------------------")
|
|
400
396
|
|
|
401
397
|
status_code = error.status_code if hasattr(error, "status_code") else 500
|
|
402
398
|
message = str(error)
|
|
403
399
|
stacktrace = format_exception(error, value=error, tb=error.__traceback__) # type: ignore
|
|
404
400
|
detail = {"message": message, "stacktrace": stacktrace}
|
|
405
401
|
|
|
406
|
-
log.error(f"----------------------------------")
|
|
407
|
-
log.error(f"Agenta SDK - exiting with failure: {status_code}")
|
|
408
|
-
log.error(f"----------------------------------")
|
|
409
|
-
|
|
410
402
|
raise HTTPException(status_code=status_code, detail=detail)
|
|
411
403
|
|
|
412
404
|
def patch_result(self, result: Any):
|
|
@@ -683,10 +675,7 @@ class entrypoint:
|
|
|
683
675
|
|
|
684
676
|
loop = get_event_loop()
|
|
685
677
|
|
|
686
|
-
with routing_context_manager(
|
|
687
|
-
config=args_config_params,
|
|
688
|
-
environment="terminal",
|
|
689
|
-
):
|
|
678
|
+
with routing_context_manager(config=args_config_params):
|
|
690
679
|
result = loop.run_until_complete(
|
|
691
680
|
self.execute_function(
|
|
692
681
|
func,
|
|
@@ -695,30 +684,23 @@ class entrypoint:
|
|
|
695
684
|
)
|
|
696
685
|
)
|
|
697
686
|
|
|
698
|
-
SHOW_DETAILS = True
|
|
699
|
-
SHOW_DATA = False
|
|
700
|
-
SHOW_TRACE = False
|
|
701
|
-
|
|
702
687
|
if result.trace:
|
|
703
688
|
log.info("\n========= Result =========\n")
|
|
704
689
|
|
|
705
690
|
log.info(f"trace_id: {result.trace['trace_id']}")
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
log.info(f"----------------")
|
|
720
|
-
log.info(dumps(result.trace.get("spans", []), indent=2))
|
|
721
|
-
log.info(f"----------------")
|
|
691
|
+
log.info(f"latency: {result.trace.get('latency')}")
|
|
692
|
+
log.info(f"cost: {result.trace.get('cost')}")
|
|
693
|
+
log.info(f"usage: {list(result.trace.get('usage', {}).values())}")
|
|
694
|
+
|
|
695
|
+
log.info(" ")
|
|
696
|
+
log.info("data:")
|
|
697
|
+
log.info(dumps(result.data, indent=2))
|
|
698
|
+
|
|
699
|
+
log.info(" ")
|
|
700
|
+
log.info("trace:")
|
|
701
|
+
log.info("----------------")
|
|
702
|
+
log.info(dumps(result.trace.get("spans", []), indent=2))
|
|
703
|
+
log.info("----------------")
|
|
722
704
|
|
|
723
705
|
log.info("\n==========================\n")
|
|
724
706
|
|
agenta/sdk/litellm/litellm.py
CHANGED
|
@@ -60,7 +60,11 @@ def litellm_handler():
|
|
|
60
60
|
)
|
|
61
61
|
|
|
62
62
|
if not self.span:
|
|
63
|
-
log.
|
|
63
|
+
log.warning("Agenta SDK - litellm tracing failed")
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
if not self.span.is_recording():
|
|
67
|
+
log.error("Agenta SDK - litellm span not recording.")
|
|
64
68
|
return
|
|
65
69
|
|
|
66
70
|
self.span.set_attributes(
|
|
@@ -86,43 +90,11 @@ def litellm_handler():
|
|
|
86
90
|
end_time,
|
|
87
91
|
):
|
|
88
92
|
if not self.span:
|
|
89
|
-
log.
|
|
93
|
+
log.warning("Agenta SDK - litellm tracing failed")
|
|
90
94
|
return
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
for choice in response_obj.choices:
|
|
95
|
-
message = choice.message.__dict__
|
|
96
|
-
result.append(message)
|
|
97
|
-
|
|
98
|
-
outputs = {"completion": result}
|
|
99
|
-
self.span.set_attributes(
|
|
100
|
-
attributes={"outputs": outputs},
|
|
101
|
-
namespace="data",
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
except Exception as e:
|
|
105
|
-
pass
|
|
106
|
-
|
|
107
|
-
self.span.set_attributes(
|
|
108
|
-
attributes={"total": kwargs.get("response_cost")},
|
|
109
|
-
namespace="metrics.unit.costs",
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
self.span.set_attributes(
|
|
113
|
-
attributes=(
|
|
114
|
-
{
|
|
115
|
-
"prompt": response_obj.usage.prompt_tokens,
|
|
116
|
-
"completion": response_obj.usage.completion_tokens,
|
|
117
|
-
"total": response_obj.usage.total_tokens,
|
|
118
|
-
}
|
|
119
|
-
),
|
|
120
|
-
namespace="metrics.unit.tokens",
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
self.span.set_status(status="OK")
|
|
124
|
-
|
|
125
|
-
self.span.end()
|
|
96
|
+
if not self.span.is_recording():
|
|
97
|
+
return
|
|
126
98
|
|
|
127
99
|
def log_success_event(
|
|
128
100
|
self,
|
|
@@ -131,8 +103,14 @@ def litellm_handler():
|
|
|
131
103
|
start_time,
|
|
132
104
|
end_time,
|
|
133
105
|
):
|
|
106
|
+
if kwargs.get("stream"):
|
|
107
|
+
return
|
|
108
|
+
|
|
134
109
|
if not self.span:
|
|
135
|
-
log.
|
|
110
|
+
log.warning("Agenta SDK - litellm tracing failed")
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
if not self.span.is_recording():
|
|
136
114
|
return
|
|
137
115
|
|
|
138
116
|
try:
|
|
@@ -178,7 +156,10 @@ def litellm_handler():
|
|
|
178
156
|
end_time,
|
|
179
157
|
):
|
|
180
158
|
if not self.span:
|
|
181
|
-
log.
|
|
159
|
+
log.warning("Agenta SDK - litellm tracing failed")
|
|
160
|
+
return
|
|
161
|
+
|
|
162
|
+
if not self.span.is_recording():
|
|
182
163
|
return
|
|
183
164
|
|
|
184
165
|
self.span.record_exception(kwargs["exception"])
|
|
@@ -195,43 +176,11 @@ def litellm_handler():
|
|
|
195
176
|
end_time,
|
|
196
177
|
):
|
|
197
178
|
if not self.span:
|
|
198
|
-
log.
|
|
179
|
+
log.warning("Agenta SDK - litellm tracing failed")
|
|
199
180
|
return
|
|
200
181
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
for choice in response_obj.choices:
|
|
204
|
-
message = choice.message.__dict__
|
|
205
|
-
result.append(message)
|
|
206
|
-
|
|
207
|
-
outputs = {"completion": result}
|
|
208
|
-
self.span.set_attributes(
|
|
209
|
-
attributes={"outputs": outputs},
|
|
210
|
-
namespace="data",
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
except Exception as e:
|
|
214
|
-
pass
|
|
215
|
-
|
|
216
|
-
self.span.set_attributes(
|
|
217
|
-
attributes={"total": kwargs.get("response_cost")},
|
|
218
|
-
namespace="metrics.unit.costs",
|
|
219
|
-
)
|
|
220
|
-
|
|
221
|
-
self.span.set_attributes(
|
|
222
|
-
attributes=(
|
|
223
|
-
{
|
|
224
|
-
"prompt": response_obj.usage.prompt_tokens,
|
|
225
|
-
"completion": response_obj.usage.completion_tokens,
|
|
226
|
-
"total": response_obj.usage.total_tokens,
|
|
227
|
-
}
|
|
228
|
-
),
|
|
229
|
-
namespace="metrics.unit.tokens",
|
|
230
|
-
)
|
|
231
|
-
|
|
232
|
-
self.span.set_status(status="OK")
|
|
233
|
-
|
|
234
|
-
self.span.end()
|
|
182
|
+
if not self.span.is_recording():
|
|
183
|
+
return
|
|
235
184
|
|
|
236
185
|
async def async_log_success_event(
|
|
237
186
|
self,
|
|
@@ -241,7 +190,10 @@ def litellm_handler():
|
|
|
241
190
|
end_time,
|
|
242
191
|
):
|
|
243
192
|
if not self.span:
|
|
244
|
-
log.
|
|
193
|
+
log.warning("Agenta SDK - litellm tracing failed")
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
if not self.span.is_recording():
|
|
245
197
|
return
|
|
246
198
|
|
|
247
199
|
try:
|
|
@@ -287,7 +239,10 @@ def litellm_handler():
|
|
|
287
239
|
end_time,
|
|
288
240
|
):
|
|
289
241
|
if not self.span:
|
|
290
|
-
log.
|
|
242
|
+
log.warning("Agenta SDK - litellm tracing failed")
|
|
243
|
+
return
|
|
244
|
+
|
|
245
|
+
if not self.span.is_recording():
|
|
291
246
|
return
|
|
292
247
|
|
|
293
248
|
self.span.record_exception(kwargs["exception"])
|
agenta/sdk/middleware/auth.py
CHANGED
|
@@ -133,10 +133,10 @@ class AuthorizationMiddleware(BaseHTTPMiddleware):
|
|
|
133
133
|
return await call_next(request)
|
|
134
134
|
|
|
135
135
|
except: # pylint: disable=bare-except
|
|
136
|
-
log.
|
|
137
|
-
log.
|
|
138
|
-
log.
|
|
139
|
-
log.
|
|
140
|
-
log.
|
|
136
|
+
log.warning("------------------------------------------------------")
|
|
137
|
+
log.warning("Agenta SDK - handling auth middleware exception below:")
|
|
138
|
+
log.warning("------------------------------------------------------")
|
|
139
|
+
log.warning(format_exc().strip("\n"))
|
|
140
|
+
log.warning("------------------------------------------------------")
|
|
141
141
|
|
|
142
142
|
return Deny()
|
agenta/sdk/tracing/context.py
CHANGED
|
@@ -14,11 +14,11 @@ def tracing_context_manager():
|
|
|
14
14
|
token = tracing_context.set(_tracing_context)
|
|
15
15
|
try:
|
|
16
16
|
yield
|
|
17
|
-
except
|
|
18
|
-
log.
|
|
19
|
-
log.
|
|
20
|
-
log.
|
|
21
|
-
log.
|
|
22
|
-
log.
|
|
17
|
+
except: # pylint: disable=bare-except
|
|
18
|
+
log.warning("----------------------------------------------")
|
|
19
|
+
log.warning("Agenta SDK - handling tracing exception below:")
|
|
20
|
+
log.warning("----------------------------------------------")
|
|
21
|
+
log.warning(format_exc().strip("\n"))
|
|
22
|
+
log.warning("----------------------------------------------")
|
|
23
23
|
finally:
|
|
24
24
|
tracing_context.reset(token)
|
agenta/sdk/tracing/inline.py
CHANGED
|
@@ -903,9 +903,9 @@ def parse_to_agenta_span_dto(
|
|
|
903
903
|
if span_dto.data:
|
|
904
904
|
span_dto.data = _unmarshal_attributes(span_dto.data)
|
|
905
905
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
906
|
+
if "outputs" in span_dto.data:
|
|
907
|
+
if "__default__" in span_dto.data["outputs"]:
|
|
908
|
+
span_dto.data["outputs"] = span_dto.data["outputs"]["__default__"]
|
|
909
909
|
|
|
910
910
|
# METRICS
|
|
911
911
|
if span_dto.metrics:
|
|
@@ -934,6 +934,17 @@ def parse_to_agenta_span_dto(
|
|
|
934
934
|
else:
|
|
935
935
|
parse_to_agenta_span_dto(v)
|
|
936
936
|
|
|
937
|
+
# MASK LINKS FOR NOW
|
|
938
|
+
span_dto.links = None
|
|
939
|
+
# ------------------
|
|
940
|
+
|
|
941
|
+
# MASK LIFECYCLE FOR NOW
|
|
942
|
+
# span_dto.lifecycle = None
|
|
943
|
+
if span_dto.lifecycle:
|
|
944
|
+
span_dto.lifecycle.updated_at = None
|
|
945
|
+
span_dto.lifecycle.updated_by_id = None
|
|
946
|
+
# ----------------------
|
|
947
|
+
|
|
937
948
|
return span_dto
|
|
938
949
|
|
|
939
950
|
|
|
@@ -945,6 +956,8 @@ def parse_to_agenta_span_dto(
|
|
|
945
956
|
from litellm import cost_calculator
|
|
946
957
|
from opentelemetry.sdk.trace import ReadableSpan
|
|
947
958
|
|
|
959
|
+
from agenta.sdk.types import AgentaNodeDto, AgentaNodesResponse
|
|
960
|
+
|
|
948
961
|
|
|
949
962
|
def parse_inline_trace(
|
|
950
963
|
spans: Dict[str, ReadableSpan],
|
|
@@ -992,51 +1005,19 @@ def parse_inline_trace(
|
|
|
992
1005
|
### services.observability.service.query() ###
|
|
993
1006
|
##############################################
|
|
994
1007
|
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
tokens = {
|
|
1009
|
-
"prompt_tokens": root_span.metrics.get("acc", {})
|
|
1010
|
-
.get("tokens", {})
|
|
1011
|
-
.get("prompt", 0),
|
|
1012
|
-
"completion_tokens": root_span.metrics.get("acc", {})
|
|
1013
|
-
.get("tokens", {})
|
|
1014
|
-
.get("completion", 0),
|
|
1015
|
-
"total_tokens": root_span.metrics.get("acc", {})
|
|
1016
|
-
.get("tokens", {})
|
|
1017
|
-
.get("total", 0),
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
spans = [
|
|
1021
|
-
loads(span.model_dump_json(exclude_none=True)) for span in legacy_spans
|
|
1022
|
-
]
|
|
1023
|
-
|
|
1024
|
-
inline_trace = {
|
|
1025
|
-
"trace_id": trace_id,
|
|
1026
|
-
"latency": latency,
|
|
1027
|
-
"cost": cost,
|
|
1028
|
-
"usage": tokens,
|
|
1029
|
-
"spans": spans,
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
else:
|
|
1033
|
-
spans = [
|
|
1034
|
-
loads(span_dto.model_dump_json(exclude_none=True))
|
|
1035
|
-
for span_dto in agenta_span_dtos
|
|
1036
|
-
]
|
|
1037
|
-
|
|
1038
|
-
inline_trace = spans # turn into Agenta Model ?
|
|
1039
|
-
|
|
1008
|
+
spans = [
|
|
1009
|
+
loads(
|
|
1010
|
+
span_dto.model_dump_json(
|
|
1011
|
+
exclude_none=True,
|
|
1012
|
+
exclude_defaults=True,
|
|
1013
|
+
)
|
|
1014
|
+
)
|
|
1015
|
+
for span_dto in agenta_span_dtos
|
|
1016
|
+
]
|
|
1017
|
+
inline_trace = AgentaNodesResponse(
|
|
1018
|
+
version="1.0.0",
|
|
1019
|
+
nodes=[AgentaNodeDto(**span) for span in spans],
|
|
1020
|
+
).model_dump(exclude_none=True, exclude_unset=True)
|
|
1040
1021
|
return inline_trace
|
|
1041
1022
|
|
|
1042
1023
|
|
|
@@ -1120,98 +1101,6 @@ class LlmTokens(BaseModel):
|
|
|
1120
1101
|
total_tokens: Optional[int] = 0
|
|
1121
1102
|
|
|
1122
1103
|
|
|
1123
|
-
class CreateSpan(BaseModel):
|
|
1124
|
-
id: str
|
|
1125
|
-
app_id: str
|
|
1126
|
-
variant_id: Optional[str] = None
|
|
1127
|
-
variant_name: Optional[str] = None
|
|
1128
|
-
inputs: Optional[Dict[str, Optional[Any]]] = None
|
|
1129
|
-
internals: Optional[Dict[str, Optional[Any]]] = None
|
|
1130
|
-
outputs: Optional[Union[str, Dict[str, Optional[Any]], List[Any]]] = None
|
|
1131
|
-
config: Optional[Dict[str, Optional[Any]]] = None
|
|
1132
|
-
environment: Optional[str] = None
|
|
1133
|
-
tags: Optional[List[str]] = None
|
|
1134
|
-
token_consumption: Optional[int] = None
|
|
1135
|
-
name: str
|
|
1136
|
-
parent_span_id: Optional[str] = None
|
|
1137
|
-
attributes: Optional[Dict[str, Optional[Any]]] = None
|
|
1138
|
-
spankind: str
|
|
1139
|
-
status: str
|
|
1140
|
-
user: Optional[str] = None
|
|
1141
|
-
start_time: datetime
|
|
1142
|
-
end_time: datetime
|
|
1143
|
-
tokens: Optional[LlmTokens] = None
|
|
1144
|
-
cost: Optional[float] = None
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
def _parse_to_legacy_span(span: SpanDTO) -> CreateSpan:
|
|
1148
|
-
attributes = None
|
|
1149
|
-
if span.otel:
|
|
1150
|
-
attributes = span.otel.attributes or {}
|
|
1151
|
-
|
|
1152
|
-
if span.otel.events:
|
|
1153
|
-
for event in span.otel.events:
|
|
1154
|
-
if event.name == "exception":
|
|
1155
|
-
attributes.update(**event.attributes)
|
|
1156
|
-
|
|
1157
|
-
legacy_span = CreateSpan(
|
|
1158
|
-
id=span.node.id.hex[:24],
|
|
1159
|
-
spankind=span.node.type,
|
|
1160
|
-
name=span.node.name,
|
|
1161
|
-
#
|
|
1162
|
-
status=span.status.code.name,
|
|
1163
|
-
#
|
|
1164
|
-
start_time=span.time.start,
|
|
1165
|
-
end_time=span.time.end,
|
|
1166
|
-
#
|
|
1167
|
-
parent_span_id=span.parent.id.hex[:24] if span.parent else None,
|
|
1168
|
-
#
|
|
1169
|
-
inputs=span.data.get("inputs") if span.data else {},
|
|
1170
|
-
internals=span.data.get("internals") if span.data else {},
|
|
1171
|
-
outputs=span.data.get("outputs") if span.data else {},
|
|
1172
|
-
#
|
|
1173
|
-
environment=span.meta.get("environment") if span.meta else None,
|
|
1174
|
-
config=span.meta.get("configuration") if span.meta else None,
|
|
1175
|
-
#
|
|
1176
|
-
tokens=(
|
|
1177
|
-
LlmTokens(
|
|
1178
|
-
prompt_tokens=span.metrics.get("acc", {})
|
|
1179
|
-
.get("tokens", {})
|
|
1180
|
-
.get("prompt", 0.0),
|
|
1181
|
-
completion_tokens=span.metrics.get("acc", {})
|
|
1182
|
-
.get("tokens", {})
|
|
1183
|
-
.get("completion", 0.0),
|
|
1184
|
-
total_tokens=span.metrics.get("acc", {})
|
|
1185
|
-
.get("tokens", {})
|
|
1186
|
-
.get("total", 0.0),
|
|
1187
|
-
)
|
|
1188
|
-
if span.metrics
|
|
1189
|
-
else None
|
|
1190
|
-
),
|
|
1191
|
-
cost=(
|
|
1192
|
-
span.metrics.get("acc", {}).get("costs", {}).get("total", 0.0)
|
|
1193
|
-
if span.metrics
|
|
1194
|
-
else None
|
|
1195
|
-
),
|
|
1196
|
-
#
|
|
1197
|
-
app_id=(
|
|
1198
|
-
span.refs.get("application", {}).get("id", "missing-app-id")
|
|
1199
|
-
if span.refs
|
|
1200
|
-
else "missing-app-id"
|
|
1201
|
-
),
|
|
1202
|
-
#
|
|
1203
|
-
attributes=attributes,
|
|
1204
|
-
#
|
|
1205
|
-
variant_id=None,
|
|
1206
|
-
variant_name=None,
|
|
1207
|
-
tags=None,
|
|
1208
|
-
token_consumption=None,
|
|
1209
|
-
user=None,
|
|
1210
|
-
)
|
|
1211
|
-
|
|
1212
|
-
return legacy_span
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
1104
|
TYPES_WITH_COSTS = [
|
|
1216
1105
|
"embedding",
|
|
1217
1106
|
"query",
|
|
@@ -1229,13 +1118,15 @@ def calculate_costs(span_idx: Dict[str, SpanDTO]):
|
|
|
1229
1118
|
and span.meta
|
|
1230
1119
|
and span.metrics
|
|
1231
1120
|
):
|
|
1121
|
+
model = span.meta.get("response.model")
|
|
1122
|
+
prompt_tokens = span.metrics.get("unit.tokens.prompt", 0.0)
|
|
1123
|
+
completion_tokens = span.metrics.get("unit.tokens.completion", 0.0)
|
|
1124
|
+
|
|
1232
1125
|
try:
|
|
1233
1126
|
costs = cost_calculator.cost_per_token(
|
|
1234
|
-
model=
|
|
1235
|
-
prompt_tokens=
|
|
1236
|
-
completion_tokens=
|
|
1237
|
-
call_type=span.node.type.name.lower(),
|
|
1238
|
-
response_time_ms=span.time.span // 1_000,
|
|
1127
|
+
model=model,
|
|
1128
|
+
prompt_tokens=prompt_tokens,
|
|
1129
|
+
completion_tokens=completion_tokens,
|
|
1239
1130
|
)
|
|
1240
1131
|
|
|
1241
1132
|
if not costs:
|
|
@@ -1248,5 +1139,8 @@ def calculate_costs(span_idx: Dict[str, SpanDTO]):
|
|
|
1248
1139
|
span.metrics["unit.costs.completion"] = completion_cost
|
|
1249
1140
|
span.metrics["unit.costs.total"] = total_cost
|
|
1250
1141
|
|
|
1251
|
-
except:
|
|
1252
|
-
|
|
1142
|
+
except: # pylint: disable=bare-except
|
|
1143
|
+
print("Failed to calculate costs:")
|
|
1144
|
+
print(
|
|
1145
|
+
f"model={model}, prompt_tokens={prompt_tokens}, completion_tokens={completion_tokens}"
|
|
1146
|
+
)
|
agenta/sdk/tracing/processors.py
CHANGED
|
@@ -91,9 +91,7 @@ class TraceProcessor(BatchSpanProcessor):
|
|
|
91
91
|
ret = super().force_flush(timeout_millis)
|
|
92
92
|
|
|
93
93
|
if not ret:
|
|
94
|
-
log.
|
|
95
|
-
log.error("Agenta SDK - skipping export due to timeout.")
|
|
96
|
-
log.error("--------------------------------------------")
|
|
94
|
+
log.warning("Agenta SDK - skipping export due to timeout.")
|
|
97
95
|
|
|
98
96
|
def is_ready(
|
|
99
97
|
self,
|
agenta/sdk/tracing/tracing.py
CHANGED
|
@@ -90,7 +90,6 @@ class Tracing(metaclass=Singleton):
|
|
|
90
90
|
self.otlp_url,
|
|
91
91
|
)
|
|
92
92
|
log.info("--------------------------------------------")
|
|
93
|
-
|
|
94
93
|
check(
|
|
95
94
|
self.otlp_url,
|
|
96
95
|
headers=self.headers,
|
|
@@ -106,13 +105,10 @@ class Tracing(metaclass=Singleton):
|
|
|
106
105
|
)
|
|
107
106
|
|
|
108
107
|
self.tracer_provider.add_span_processor(_otlp)
|
|
109
|
-
|
|
110
108
|
log.info("Success: traces will be exported.")
|
|
111
109
|
log.info("--------------------------------------------")
|
|
112
|
-
|
|
113
110
|
except: # pylint: disable=bare-except
|
|
114
|
-
log.warning("
|
|
115
|
-
log.warning("--------------------------------------------")
|
|
111
|
+
log.warning("Agenta SDK - traces will not be exported.")
|
|
116
112
|
|
|
117
113
|
# GLOBAL TRACER PROVIDER -- INSTRUMENTATION LIBRARIES
|
|
118
114
|
set_tracer_provider(self.tracer_provider)
|
agenta/sdk/types.py
CHANGED
|
@@ -4,6 +4,9 @@ from typing import Dict, List, Optional, Any, Union
|
|
|
4
4
|
|
|
5
5
|
from pydantic import ConfigDict, BaseModel, HttpUrl
|
|
6
6
|
|
|
7
|
+
from agenta.client.backend.types.agenta_node_dto import AgentaNodeDto
|
|
8
|
+
from agenta.client.backend.types.agenta_nodes_response import AgentaNodesResponse
|
|
9
|
+
|
|
7
10
|
|
|
8
11
|
@dataclass
|
|
9
12
|
class MultipleChoice:
|
|
@@ -23,9 +26,9 @@ class LLMTokenUsage(BaseModel):
|
|
|
23
26
|
|
|
24
27
|
|
|
25
28
|
class BaseResponse(BaseModel):
|
|
26
|
-
version: Optional[str] = "
|
|
29
|
+
version: Optional[str] = "3.0"
|
|
27
30
|
data: Optional[Union[str, Dict[str, Any]]] = None
|
|
28
|
-
|
|
31
|
+
tree: Optional[AgentaNodesResponse] = None
|
|
29
32
|
|
|
30
33
|
|
|
31
34
|
class DictInput(dict):
|
agenta/sdk/utils/exceptions.py
CHANGED
|
@@ -17,11 +17,11 @@ class suppress(AbstractContextManager): # pylint: disable=invalid-name
|
|
|
17
17
|
if exc_type is None:
|
|
18
18
|
return True
|
|
19
19
|
else:
|
|
20
|
-
log.
|
|
21
|
-
log.
|
|
22
|
-
log.
|
|
23
|
-
log.
|
|
24
|
-
log.
|
|
20
|
+
log.warning("-------------------------------------------------")
|
|
21
|
+
log.warning("Agenta SDK - suppressing tracing exception below:")
|
|
22
|
+
log.warning("-------------------------------------------------")
|
|
23
|
+
log.warning(format_exc().strip("\n"))
|
|
24
|
+
log.warning("-------------------------------------------------")
|
|
25
25
|
return True
|
|
26
26
|
|
|
27
27
|
|
|
@@ -34,8 +34,11 @@ def handle_exceptions():
|
|
|
34
34
|
try:
|
|
35
35
|
return await func(*args, **kwargs)
|
|
36
36
|
except Exception as e:
|
|
37
|
-
log.
|
|
38
|
-
log.
|
|
37
|
+
log.warning("------------------------------------------")
|
|
38
|
+
log.warning("Agenta SDK - intercepting exception below:")
|
|
39
|
+
log.warning("------------------------------------------")
|
|
40
|
+
log.warning(format_exc().strip("\n"))
|
|
41
|
+
log.warning("------------------------------------------")
|
|
39
42
|
raise e
|
|
40
43
|
|
|
41
44
|
@wraps(func)
|
|
@@ -43,8 +46,11 @@ def handle_exceptions():
|
|
|
43
46
|
try:
|
|
44
47
|
return func(*args, **kwargs)
|
|
45
48
|
except Exception as e:
|
|
46
|
-
log.
|
|
47
|
-
log.
|
|
49
|
+
log.warning("------------------------------------------")
|
|
50
|
+
log.warning("Agenta SDK - intercepting exception below:")
|
|
51
|
+
log.warning("------------------------------------------")
|
|
52
|
+
log.warning(format_exc().strip("\n"))
|
|
53
|
+
log.warning("------------------------------------------")
|
|
48
54
|
raise e
|
|
49
55
|
|
|
50
56
|
return async_wrapper if is_coroutine_function else sync_wrapper
|
agenta/sdk/utils/logging.py
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from os import getenv
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
class Logger:
|
|
5
|
-
def __init__(self, name="agenta.logger", level=logging.
|
|
6
|
+
def __init__(self, name="agenta.logger", level=logging.WARNING):
|
|
7
|
+
if getenv("AGENTA_DEBUG"):
|
|
8
|
+
level = logging.DEBUG
|
|
9
|
+
|
|
6
10
|
self.logger = logging.getLogger(name)
|
|
7
11
|
self.logger.setLevel(level)
|
|
8
12
|
|