agenta 0.27.7__py3-none-any.whl → 0.27.7a0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of agenta might be problematic. Click here for more details.

Files changed (61) hide show
  1. agenta/cli/main.py +51 -4
  2. agenta/client/backend/__init__.py +0 -63
  3. agenta/client/backend/apps/client.py +58 -12
  4. agenta/client/backend/client.py +22 -22
  5. agenta/client/backend/core/http_client.py +7 -15
  6. agenta/client/backend/evaluations/client.py +11 -0
  7. agenta/client/backend/observability/client.py +4 -4
  8. agenta/client/backend/testsets/client.py +40 -8
  9. agenta/client/backend/types/__init__.py +0 -58
  10. agenta/client/backend/variants/client.py +16 -24
  11. agenta/sdk/__init__.py +0 -2
  12. agenta/sdk/agenta_init.py +9 -4
  13. agenta/sdk/decorators/routing.py +42 -24
  14. agenta/sdk/litellm/litellm.py +75 -30
  15. agenta/sdk/middleware/auth.py +6 -9
  16. agenta/sdk/tracing/context.py +6 -6
  17. agenta/sdk/tracing/inline.py +151 -48
  18. agenta/sdk/tracing/processors.py +3 -1
  19. agenta/sdk/tracing/tracing.py +5 -1
  20. agenta/sdk/types.py +2 -5
  21. agenta/sdk/utils/debug.py +68 -0
  22. agenta/sdk/utils/exceptions.py +9 -15
  23. agenta/sdk/utils/logging.py +1 -5
  24. {agenta-0.27.7.dist-info → agenta-0.27.7a0.dist-info}/METADATA +1 -1
  25. {agenta-0.27.7.dist-info → agenta-0.27.7a0.dist-info}/RECORD +27 -60
  26. agenta/client/backend/observability_v_1/__init__.py +0 -5
  27. agenta/client/backend/observability_v_1/client.py +0 -560
  28. agenta/client/backend/observability_v_1/types/__init__.py +0 -6
  29. agenta/client/backend/observability_v_1/types/format.py +0 -5
  30. agenta/client/backend/observability_v_1/types/query_traces_response.py +0 -11
  31. agenta/client/backend/types/agenta_node_dto.py +0 -48
  32. agenta/client/backend/types/agenta_node_dto_nodes_value.py +0 -6
  33. agenta/client/backend/types/agenta_nodes_response.py +0 -30
  34. agenta/client/backend/types/agenta_root_dto.py +0 -30
  35. agenta/client/backend/types/agenta_roots_response.py +0 -30
  36. agenta/client/backend/types/agenta_tree_dto.py +0 -30
  37. agenta/client/backend/types/agenta_trees_response.py +0 -30
  38. agenta/client/backend/types/collect_status_response.py +0 -22
  39. agenta/client/backend/types/exception_dto.py +0 -26
  40. agenta/client/backend/types/link_dto.py +0 -24
  41. agenta/client/backend/types/node_dto.py +0 -24
  42. agenta/client/backend/types/node_type.py +0 -19
  43. agenta/client/backend/types/o_tel_context_dto.py +0 -22
  44. agenta/client/backend/types/o_tel_event_dto.py +0 -23
  45. agenta/client/backend/types/o_tel_extra_dto.py +0 -26
  46. agenta/client/backend/types/o_tel_link_dto.py +0 -23
  47. agenta/client/backend/types/o_tel_span_dto.py +0 -37
  48. agenta/client/backend/types/o_tel_span_kind.py +0 -15
  49. agenta/client/backend/types/o_tel_spans_response.py +0 -24
  50. agenta/client/backend/types/o_tel_status_code.py +0 -8
  51. agenta/client/backend/types/parent_dto.py +0 -21
  52. agenta/client/backend/types/root_dto.py +0 -21
  53. agenta/client/backend/types/span_dto.py +0 -54
  54. agenta/client/backend/types/span_dto_nodes_value.py +0 -9
  55. agenta/client/backend/types/status_code.py +0 -5
  56. agenta/client/backend/types/status_dto.py +0 -23
  57. agenta/client/backend/types/time_dto.py +0 -23
  58. agenta/client/backend/types/tree_dto.py +0 -23
  59. agenta/client/backend/types/tree_type.py +0 -5
  60. {agenta-0.27.7.dist-info → agenta-0.27.7a0.dist-info}/WHEEL +0 -0
  61. {agenta-0.27.7.dist-info → agenta-0.27.7a0.dist-info}/entry_points.txt +0 -0
@@ -143,7 +143,9 @@ class entrypoint:
143
143
  _MIDDLEWARES = False
144
144
 
145
145
  except: # pylint: disable=bare-except
146
- log.warning("Agenta SDK - failed to secure route: %s", route_path)
146
+ log.error("------------------------------------")
147
+ log.error("Agenta SDK - failed to secure route: %s", route_path)
148
+ log.error("------------------------------------")
147
149
  ### --- Update Middleware --- #
148
150
 
149
151
  DEFAULT_PATH = "generate"
@@ -355,7 +357,9 @@ class entrypoint:
355
357
  *args,
356
358
  **func_params,
357
359
  ):
358
- log.info("Agenta SDK - handling route: %s", repr(self.route_path or "/"))
360
+ log.info("---------------------------")
361
+ log.info(f"Agenta SDK - running route: {repr(self.route_path or '/')}")
362
+ log.info("---------------------------")
359
363
 
360
364
  tracing_context.set(routing_context.get())
361
365
 
@@ -373,32 +377,36 @@ class entrypoint:
373
377
 
374
378
  async def handle_success(self, result: Any, inline_trace: bool):
375
379
  data = None
376
- tree = None
380
+ trace = dict()
377
381
 
378
382
  with suppress():
379
383
  data = self.patch_result(result)
380
384
 
381
385
  if inline_trace:
382
- tree = await self.fetch_inline_trace(inline_trace)
386
+ trace = await self.fetch_inline_trace(inline_trace)
383
387
 
384
388
  log.info(f"----------------------------------")
385
389
  log.info(f"Agenta SDK - exiting with success: 200")
386
390
  log.info(f"----------------------------------")
387
391
 
388
- return BaseResponse(data=data, tree=tree)
392
+ return BaseResponse(data=data, trace=trace)
389
393
 
390
394
  def handle_failure(self, error: Exception):
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("--------------------------------------------------")
395
+ log.error("--------------------------------------------------")
396
+ log.error("Agenta SDK - handling application exception below:")
397
+ log.error("--------------------------------------------------")
398
+ log.error(format_exc().strip("\n"))
399
+ log.error("--------------------------------------------------")
396
400
 
397
401
  status_code = error.status_code if hasattr(error, "status_code") else 500
398
402
  message = str(error)
399
403
  stacktrace = format_exception(error, value=error, tb=error.__traceback__) # type: ignore
400
404
  detail = {"message": message, "stacktrace": stacktrace}
401
405
 
406
+ log.error(f"----------------------------------")
407
+ log.error(f"Agenta SDK - exiting with failure: {status_code}")
408
+ log.error(f"----------------------------------")
409
+
402
410
  raise HTTPException(status_code=status_code, detail=detail)
403
411
 
404
412
  def patch_result(self, result: Any):
@@ -675,7 +683,10 @@ class entrypoint:
675
683
 
676
684
  loop = get_event_loop()
677
685
 
678
- with routing_context_manager(config=args_config_params):
686
+ with routing_context_manager(
687
+ config=args_config_params,
688
+ environment="terminal",
689
+ ):
679
690
  result = loop.run_until_complete(
680
691
  self.execute_function(
681
692
  func,
@@ -684,23 +695,30 @@ class entrypoint:
684
695
  )
685
696
  )
686
697
 
698
+ SHOW_DETAILS = True
699
+ SHOW_DATA = False
700
+ SHOW_TRACE = False
701
+
687
702
  if result.trace:
688
703
  log.info("\n========= Result =========\n")
689
704
 
690
705
  log.info(f"trace_id: {result.trace['trace_id']}")
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("----------------")
706
+ if SHOW_DETAILS:
707
+ log.info(f"latency: {result.trace.get('latency')}")
708
+ log.info(f"cost: {result.trace.get('cost')}")
709
+ log.info(f"usage: {list(result.trace.get('usage', {}).values())}")
710
+
711
+ if SHOW_DATA:
712
+ log.info(" ")
713
+ log.info(f"data:")
714
+ log.info(dumps(result.data, indent=2))
715
+
716
+ if SHOW_TRACE:
717
+ log.info(" ")
718
+ log.info(f"trace:")
719
+ log.info(f"----------------")
720
+ log.info(dumps(result.trace.get("spans", []), indent=2))
721
+ log.info(f"----------------")
704
722
 
705
723
  log.info("\n==========================\n")
706
724
 
@@ -60,11 +60,7 @@ def litellm_handler():
60
60
  )
61
61
 
62
62
  if not self.span:
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.")
63
+ log.error("LiteLLM callback error: span not found.")
68
64
  return
69
65
 
70
66
  self.span.set_attributes(
@@ -90,11 +86,43 @@ def litellm_handler():
90
86
  end_time,
91
87
  ):
92
88
  if not self.span:
93
- log.warning("Agenta SDK - litellm tracing failed")
89
+ log.error("LiteLLM callback error: span not found.")
94
90
  return
95
91
 
96
- if not self.span.is_recording():
97
- return
92
+ try:
93
+ result = []
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()
98
126
 
99
127
  def log_success_event(
100
128
  self,
@@ -103,14 +131,8 @@ def litellm_handler():
103
131
  start_time,
104
132
  end_time,
105
133
  ):
106
- if kwargs.get("stream"):
107
- return
108
-
109
134
  if not self.span:
110
- log.warning("Agenta SDK - litellm tracing failed")
111
- return
112
-
113
- if not self.span.is_recording():
135
+ log.error("LiteLLM callback error: span not found.")
114
136
  return
115
137
 
116
138
  try:
@@ -156,10 +178,7 @@ def litellm_handler():
156
178
  end_time,
157
179
  ):
158
180
  if not self.span:
159
- log.warning("Agenta SDK - litellm tracing failed")
160
- return
161
-
162
- if not self.span.is_recording():
181
+ log.error("LiteLLM callback error: span not found.")
163
182
  return
164
183
 
165
184
  self.span.record_exception(kwargs["exception"])
@@ -176,11 +195,43 @@ def litellm_handler():
176
195
  end_time,
177
196
  ):
178
197
  if not self.span:
179
- log.warning("Agenta SDK - litellm tracing failed")
198
+ log.error("LiteLLM callback error: span not found.")
180
199
  return
181
200
 
182
- if not self.span.is_recording():
183
- return
201
+ try:
202
+ result = []
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()
184
235
 
185
236
  async def async_log_success_event(
186
237
  self,
@@ -190,10 +241,7 @@ def litellm_handler():
190
241
  end_time,
191
242
  ):
192
243
  if not self.span:
193
- log.warning("Agenta SDK - litellm tracing failed")
194
- return
195
-
196
- if not self.span.is_recording():
244
+ log.error("LiteLLM callback error: span not found.")
197
245
  return
198
246
 
199
247
  try:
@@ -239,10 +287,7 @@ def litellm_handler():
239
287
  end_time,
240
288
  ):
241
289
  if not self.span:
242
- log.warning("Agenta SDK - litellm tracing failed")
243
- return
244
-
245
- if not self.span.is_recording():
290
+ log.error("LiteLLM callback error: span not found.")
246
291
  return
247
292
 
248
293
  self.span.record_exception(kwargs["exception"])
@@ -27,8 +27,6 @@ AGENTA_SDK_AUTH_CACHE = str(environ.get("AGENTA_SDK_AUTH_CACHE", True)).lower()
27
27
  "t",
28
28
  )
29
29
 
30
- AGENTA_SDK_AUTH_CACHE = False
31
-
32
30
  AGENTA_UNAUTHORIZED_EXECUTION_ALLOWED = str(
33
31
  environ.get("AGENTA_UNAUTHORIZED_EXECUTION_ALLOWED", False)
34
32
  ).lower() in ("true", "1", "t")
@@ -63,6 +61,7 @@ class AuthorizationMiddleware(BaseHTTPMiddleware):
63
61
  self,
64
62
  request: Request,
65
63
  call_next: Callable,
64
+ project_id: Optional[UUID] = None,
66
65
  ):
67
66
  if AGENTA_UNAUTHORIZED_EXECUTION_ALLOWED:
68
67
  return await call_next(request)
@@ -84,8 +83,6 @@ class AuthorizationMiddleware(BaseHTTPMiddleware):
84
83
  "resource_id": self.resource_id,
85
84
  }
86
85
 
87
- project_id = request.query_params.get("project_id")
88
-
89
86
  if project_id:
90
87
  params["project_id"] = project_id
91
88
 
@@ -136,10 +133,10 @@ class AuthorizationMiddleware(BaseHTTPMiddleware):
136
133
  return await call_next(request)
137
134
 
138
135
  except: # pylint: disable=bare-except
139
- log.warning("------------------------------------------------------")
140
- log.warning("Agenta SDK - handling auth middleware exception below:")
141
- log.warning("------------------------------------------------------")
142
- log.warning(format_exc().strip("\n"))
143
- log.warning("------------------------------------------------------")
136
+ log.error("------------------------------------------------------")
137
+ log.error("Agenta SDK - handling auth middleware exception below:")
138
+ log.error("------------------------------------------------------")
139
+ log.error(format_exc().strip("\n"))
140
+ log.error("------------------------------------------------------")
144
141
 
145
142
  return Deny()
@@ -14,11 +14,11 @@ def tracing_context_manager():
14
14
  token = tracing_context.set(_tracing_context)
15
15
  try:
16
16
  yield
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("----------------------------------------------")
17
+ except Exception as e:
18
+ log.error("----------------------------------------------")
19
+ log.error("Agenta SDK - handling tracing exception below:")
20
+ log.error("----------------------------------------------")
21
+ log.error(format_exc().strip("\n"))
22
+ log.error("----------------------------------------------")
23
23
  finally:
24
24
  tracing_context.reset(token)
@@ -41,6 +41,7 @@ from uuid import UUID
41
41
  class TimeDTO(BaseModel):
42
42
  start: datetime
43
43
  end: datetime
44
+ span: int
44
45
 
45
46
 
46
47
  class StatusCode(Enum):
@@ -845,9 +846,12 @@ def parse_from_otel_span_dto(
845
846
  else None
846
847
  )
847
848
 
849
+ duration = (otel_span_dto.end_time - otel_span_dto.start_time).total_seconds()
850
+
848
851
  time = TimeDTO(
849
852
  start=otel_span_dto.start_time,
850
853
  end=otel_span_dto.end_time,
854
+ span=round(duration * 1_000_000), # microseconds
851
855
  )
852
856
 
853
857
  status = StatusDTO(
@@ -859,13 +863,6 @@ def parse_from_otel_span_dto(
859
863
 
860
864
  data, metrics, meta, tags, refs = _parse_from_attributes(otel_span_dto)
861
865
 
862
- duration = (otel_span_dto.end_time - otel_span_dto.start_time).total_seconds()
863
-
864
- if metrics is None:
865
- metrics = dict()
866
-
867
- metrics["acc.duration.total"] = round(duration * 1_000, 3) # milliseconds
868
-
869
866
  root_id = str(tree_id)
870
867
  if refs is not None:
871
868
  root_id = refs.get("scenario.id", root_id)
@@ -906,9 +903,9 @@ def parse_to_agenta_span_dto(
906
903
  if span_dto.data:
907
904
  span_dto.data = _unmarshal_attributes(span_dto.data)
908
905
 
909
- if "outputs" in span_dto.data:
910
- if "__default__" in span_dto.data["outputs"]:
911
- span_dto.data["outputs"] = span_dto.data["outputs"]["__default__"]
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__"]
912
909
 
913
910
  # METRICS
914
911
  if span_dto.metrics:
@@ -937,17 +934,6 @@ def parse_to_agenta_span_dto(
937
934
  else:
938
935
  parse_to_agenta_span_dto(v)
939
936
 
940
- # MASK LINKS FOR NOW
941
- span_dto.links = None
942
- # ------------------
943
-
944
- # MASK LIFECYCLE FOR NOW
945
- # span_dto.lifecycle = None
946
- if span_dto.lifecycle:
947
- span_dto.lifecycle.updated_at = None
948
- span_dto.lifecycle.updated_by_id = None
949
- # ----------------------
950
-
951
937
  return span_dto
952
938
 
953
939
 
@@ -959,8 +945,6 @@ def parse_to_agenta_span_dto(
959
945
  from litellm import cost_calculator
960
946
  from opentelemetry.sdk.trace import ReadableSpan
961
947
 
962
- from agenta.sdk.types import AgentaNodeDto, AgentaNodesResponse
963
-
964
948
 
965
949
  def parse_inline_trace(
966
950
  spans: Dict[str, ReadableSpan],
@@ -1008,19 +992,51 @@ def parse_inline_trace(
1008
992
  ### services.observability.service.query() ###
1009
993
  ##############################################
1010
994
 
1011
- spans = [
1012
- loads(
1013
- span_dto.model_dump_json(
1014
- exclude_none=True,
1015
- exclude_defaults=True,
1016
- )
1017
- )
1018
- for span_dto in agenta_span_dtos
1019
- ]
1020
- inline_trace = AgentaNodesResponse(
1021
- version="1.0.0",
1022
- nodes=[AgentaNodeDto(**span) for span in spans],
1023
- ).model_dump(exclude_none=True, exclude_unset=True)
995
+ LEGACY = True
996
+ inline_trace = None
997
+
998
+ if LEGACY:
999
+ legacy_spans = [
1000
+ _parse_to_legacy_span(span_dto) for span_dto in span_idx.values()
1001
+ ]
1002
+
1003
+ root_span = agenta_span_dtos[0]
1004
+
1005
+ trace_id = root_span.root.id.hex
1006
+ latency = root_span.time.span / 1_000_000
1007
+ cost = root_span.metrics.get("acc", {}).get("costs", {}).get("total", 0.0)
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
+
1024
1040
  return inline_trace
1025
1041
 
1026
1042
 
@@ -1104,6 +1120,98 @@ class LlmTokens(BaseModel):
1104
1120
  total_tokens: Optional[int] = 0
1105
1121
 
1106
1122
 
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
+
1107
1215
  TYPES_WITH_COSTS = [
1108
1216
  "embedding",
1109
1217
  "query",
@@ -1121,15 +1229,13 @@ def calculate_costs(span_idx: Dict[str, SpanDTO]):
1121
1229
  and span.meta
1122
1230
  and span.metrics
1123
1231
  ):
1124
- model = span.meta.get("response.model")
1125
- prompt_tokens = span.metrics.get("unit.tokens.prompt", 0.0)
1126
- completion_tokens = span.metrics.get("unit.tokens.completion", 0.0)
1127
-
1128
1232
  try:
1129
1233
  costs = cost_calculator.cost_per_token(
1130
- model=model,
1131
- prompt_tokens=prompt_tokens,
1132
- completion_tokens=completion_tokens,
1234
+ model=span.meta.get("response.model"),
1235
+ prompt_tokens=span.metrics.get("unit.tokens.prompt", 0.0),
1236
+ completion_tokens=span.metrics.get("unit.tokens.completion", 0.0),
1237
+ call_type=span.node.type.name.lower(),
1238
+ response_time_ms=span.time.span // 1_000,
1133
1239
  )
1134
1240
 
1135
1241
  if not costs:
@@ -1142,8 +1248,5 @@ def calculate_costs(span_idx: Dict[str, SpanDTO]):
1142
1248
  span.metrics["unit.costs.completion"] = completion_cost
1143
1249
  span.metrics["unit.costs.total"] = total_cost
1144
1250
 
1145
- except: # pylint: disable=bare-except
1146
- print("Failed to calculate costs:")
1147
- print(
1148
- f"model={model}, prompt_tokens={prompt_tokens}, completion_tokens={completion_tokens}"
1149
- )
1251
+ except:
1252
+ pass
@@ -91,7 +91,9 @@ class TraceProcessor(BatchSpanProcessor):
91
91
  ret = super().force_flush(timeout_millis)
92
92
 
93
93
  if not ret:
94
- log.warning("Agenta SDK - skipping export due to timeout.")
94
+ log.error("--------------------------------------------")
95
+ log.error("Agenta SDK - skipping export due to timeout.")
96
+ log.error("--------------------------------------------")
95
97
 
96
98
  def is_ready(
97
99
  self,
@@ -90,6 +90,7 @@ class Tracing(metaclass=Singleton):
90
90
  self.otlp_url,
91
91
  )
92
92
  log.info("--------------------------------------------")
93
+
93
94
  check(
94
95
  self.otlp_url,
95
96
  headers=self.headers,
@@ -105,10 +106,13 @@ class Tracing(metaclass=Singleton):
105
106
  )
106
107
 
107
108
  self.tracer_provider.add_span_processor(_otlp)
109
+
108
110
  log.info("Success: traces will be exported.")
109
111
  log.info("--------------------------------------------")
112
+
110
113
  except: # pylint: disable=bare-except
111
- log.warning("Agenta SDK - traces will not be exported.")
114
+ log.warning("Failure: traces will not be exported.")
115
+ log.warning("--------------------------------------------")
112
116
 
113
117
  # GLOBAL TRACER PROVIDER -- INSTRUMENTATION LIBRARIES
114
118
  set_tracer_provider(self.tracer_provider)
agenta/sdk/types.py CHANGED
@@ -4,9 +4,6 @@ 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
-
10
7
 
11
8
  @dataclass
12
9
  class MultipleChoice:
@@ -26,9 +23,9 @@ class LLMTokenUsage(BaseModel):
26
23
 
27
24
 
28
25
  class BaseResponse(BaseModel):
29
- version: Optional[str] = "3.0"
26
+ version: Optional[str] = "2.0"
30
27
  data: Optional[Union[str, Dict[str, Any]]] = None
31
- tree: Optional[AgentaNodesResponse] = None
28
+ trace: Optional[Dict[str, Any]] = None
32
29
 
33
30
 
34
31
  class DictInput(dict):