agenta 0.27.0a0__py3-none-any.whl → 0.27.0a2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of agenta might be problematic. Click here for more details.
- agenta/__init__.py +1 -0
- agenta/sdk/__init__.py +1 -0
- agenta/sdk/agenta_init.py +7 -6
- agenta/sdk/decorators/routing.py +36 -31
- agenta/sdk/decorators/tracing.py +8 -2
- agenta/sdk/tracing/attributes.py +0 -45
- agenta/sdk/tracing/conventions.py +24 -20
- agenta/sdk/tracing/exporters.py +3 -0
- agenta/sdk/tracing/inline.py +23 -49
- agenta/sdk/tracing/processors.py +13 -2
- agenta/sdk/tracing/tracing.py +79 -24
- agenta/sdk/utils/exceptions.py +7 -4
- {agenta-0.27.0a0.dist-info → agenta-0.27.0a2.dist-info}/METADATA +1 -1
- {agenta-0.27.0a0.dist-info → agenta-0.27.0a2.dist-info}/RECORD +16 -16
- {agenta-0.27.0a0.dist-info → agenta-0.27.0a2.dist-info}/WHEEL +0 -0
- {agenta-0.27.0a0.dist-info → agenta-0.27.0a2.dist-info}/entry_points.txt +0 -0
agenta/__init__.py
CHANGED
|
@@ -16,6 +16,7 @@ from .sdk.types import (
|
|
|
16
16
|
from .sdk.utils.logging import log as logging
|
|
17
17
|
from .sdk.tracing import Tracing
|
|
18
18
|
from .sdk.decorators.tracing import instrument
|
|
19
|
+
from .sdk.tracing.conventions import Reference
|
|
19
20
|
from .sdk.decorators.routing import entrypoint, app, route
|
|
20
21
|
from .sdk.agenta_init import Config, AgentaSingleton, init
|
|
21
22
|
from .sdk.utils.costs import calculate_token_usage
|
agenta/sdk/__init__.py
CHANGED
|
@@ -17,6 +17,7 @@ from .types import (
|
|
|
17
17
|
|
|
18
18
|
from .tracing import Tracing, get_tracer
|
|
19
19
|
from .decorators.tracing import instrument
|
|
20
|
+
from .tracing.conventions import Reference
|
|
20
21
|
from .decorators.routing import entrypoint, app, route
|
|
21
22
|
from .agenta_init import Config, AgentaSingleton, init as _init
|
|
22
23
|
from .utils.costs import calculate_token_usage
|
agenta/sdk/agenta_init.py
CHANGED
|
@@ -37,9 +37,9 @@ class AgentaSingleton:
|
|
|
37
37
|
#
|
|
38
38
|
app_id: Optional[str] = None,
|
|
39
39
|
) -> None:
|
|
40
|
-
log.info(f"
|
|
41
|
-
log.info(f"
|
|
42
|
-
log.info(f"
|
|
40
|
+
log.info(f"---------------------------")
|
|
41
|
+
log.info(f"Agenta SDK - using version: {version('agenta')}")
|
|
42
|
+
log.info(f"---------------------------")
|
|
43
43
|
|
|
44
44
|
"""Main function to initialize the singleton.
|
|
45
45
|
|
|
@@ -126,9 +126,10 @@ class Config:
|
|
|
126
126
|
self.base_id = base_id
|
|
127
127
|
|
|
128
128
|
if self.base_id is None:
|
|
129
|
-
print(
|
|
130
|
-
|
|
131
|
-
)
|
|
129
|
+
# print(
|
|
130
|
+
# "Warning: Your configuration will not be saved permanently since base_id is not provided.\n"
|
|
131
|
+
# )
|
|
132
|
+
pass
|
|
132
133
|
|
|
133
134
|
if base_id is None or host is None:
|
|
134
135
|
self.persist = False
|
agenta/sdk/decorators/routing.py
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
"""The code for the Agenta SDK"""
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
import sys
|
|
5
|
-
import time
|
|
6
1
|
import json
|
|
7
2
|
import inspect
|
|
8
3
|
import argparse
|
|
@@ -12,7 +7,6 @@ import functools
|
|
|
12
7
|
from pathlib import Path
|
|
13
8
|
from tempfile import NamedTemporaryFile
|
|
14
9
|
from typing import Any, Callable, Dict, Optional, Tuple, List
|
|
15
|
-
from importlib.metadata import version
|
|
16
10
|
from fastapi.middleware.cors import CORSMiddleware
|
|
17
11
|
from fastapi import Body, FastAPI, UploadFile, HTTPException
|
|
18
12
|
|
|
@@ -44,8 +38,8 @@ from typing import Type
|
|
|
44
38
|
from annotated_types import Ge, Le, Gt, Lt
|
|
45
39
|
|
|
46
40
|
from pydantic import BaseModel, HttpUrl
|
|
47
|
-
|
|
48
|
-
from
|
|
41
|
+
|
|
42
|
+
from traceback import format_exc
|
|
49
43
|
|
|
50
44
|
|
|
51
45
|
app = FastAPI()
|
|
@@ -369,11 +363,11 @@ class entrypoint:
|
|
|
369
363
|
*args,
|
|
370
364
|
**func_params,
|
|
371
365
|
):
|
|
372
|
-
log.info(f"
|
|
366
|
+
log.info(f"---------------------------")
|
|
373
367
|
log.info(
|
|
374
|
-
f"
|
|
368
|
+
f"Agenta SDK - running route: {repr(self.route_path if self.route_path != '' else '/')}"
|
|
375
369
|
)
|
|
376
|
-
log.info(f"
|
|
370
|
+
log.info(f"---------------------------")
|
|
377
371
|
|
|
378
372
|
tracing_context.set(routing_context.get())
|
|
379
373
|
|
|
@@ -394,9 +388,11 @@ class entrypoint:
|
|
|
394
388
|
)
|
|
395
389
|
data = self.patch_result(result)
|
|
396
390
|
except Exception as e:
|
|
397
|
-
log.error(
|
|
398
|
-
|
|
399
|
-
|
|
391
|
+
log.error("--------------------------------------------------")
|
|
392
|
+
log.error("Agenta SDK - handling application exception below:")
|
|
393
|
+
log.error("--------------------------------------------------")
|
|
394
|
+
log.error(format_exc().strip("\n"))
|
|
395
|
+
log.error("--------------------------------------------------")
|
|
400
396
|
|
|
401
397
|
self.handle_exception(e)
|
|
402
398
|
|
|
@@ -426,6 +422,10 @@ class entrypoint:
|
|
|
426
422
|
|
|
427
423
|
response = BaseResponse(data=data, trace=trace)
|
|
428
424
|
|
|
425
|
+
log.info(f"----------------------------------")
|
|
426
|
+
log.info(f"Agenta SDK - exiting successfully: 200")
|
|
427
|
+
log.info(f"----------------------------------")
|
|
428
|
+
|
|
429
429
|
return response
|
|
430
430
|
|
|
431
431
|
def handle_exception(self, e: Exception):
|
|
@@ -434,6 +434,10 @@ class entrypoint:
|
|
|
434
434
|
stacktrace = traceback.format_exception(e, value=e, tb=e.__traceback__) # type: ignore
|
|
435
435
|
detail = {"message": message, "stacktrace": stacktrace}
|
|
436
436
|
|
|
437
|
+
log.error(f"----------------------------------------")
|
|
438
|
+
log.error(f"Agenta SDK - exiting with HTTPException: {status_code}")
|
|
439
|
+
log.error(f"----------------------------------------")
|
|
440
|
+
|
|
437
441
|
raise HTTPException(
|
|
438
442
|
status_code=status_code,
|
|
439
443
|
detail=detail,
|
|
@@ -658,27 +662,28 @@ class entrypoint:
|
|
|
658
662
|
SHOW_DATA = False
|
|
659
663
|
SHOW_TRACE = False
|
|
660
664
|
|
|
661
|
-
|
|
665
|
+
if result.trace:
|
|
666
|
+
log.info("\n========= Result =========\n")
|
|
662
667
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
+
log.info(f"trace_id: {result.trace['trace_id']}")
|
|
669
|
+
if SHOW_DETAILS:
|
|
670
|
+
log.info(f"latency: {result.trace.get('latency')}")
|
|
671
|
+
log.info(f"cost: {result.trace.get('cost')}")
|
|
672
|
+
log.info(f"usage: {list(result.trace.get('usage', {}).values())}")
|
|
668
673
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
674
|
+
if SHOW_DATA:
|
|
675
|
+
log.info(" ")
|
|
676
|
+
log.info(f"data:")
|
|
677
|
+
log.info(json.dumps(result.data, indent=2))
|
|
673
678
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
679
|
+
if SHOW_TRACE:
|
|
680
|
+
log.info(" ")
|
|
681
|
+
log.info(f"trace:")
|
|
682
|
+
log.info(f"----------------")
|
|
683
|
+
log.info(json.dumps(result.trace.get("spans", []), indent=2))
|
|
684
|
+
log.info(f"----------------")
|
|
680
685
|
|
|
681
|
-
|
|
686
|
+
log.info("\n==========================\n")
|
|
682
687
|
|
|
683
688
|
def override_config_in_schema(
|
|
684
689
|
self,
|
agenta/sdk/decorators/tracing.py
CHANGED
|
@@ -2,7 +2,7 @@ import inspect
|
|
|
2
2
|
import traceback
|
|
3
3
|
from functools import wraps
|
|
4
4
|
from itertools import chain
|
|
5
|
-
from typing import Callable, Optional, Any, Dict, List
|
|
5
|
+
from typing import Callable, Optional, Any, Dict, List, Union
|
|
6
6
|
|
|
7
7
|
import agenta as ag
|
|
8
8
|
|
|
@@ -47,7 +47,7 @@ class instrument:
|
|
|
47
47
|
return inputs
|
|
48
48
|
|
|
49
49
|
def redact(
|
|
50
|
-
io: Dict[str, Any], ignore: List[str]
|
|
50
|
+
io: Dict[str, Any], ignore: Union[List[str], bool] = False
|
|
51
51
|
) -> Dict[str, Any]:
|
|
52
52
|
"""
|
|
53
53
|
Redact user-defined sensitive information from inputs and outputs as defined by the ignore list or boolean flag.
|
|
@@ -147,6 +147,9 @@ class instrument:
|
|
|
147
147
|
cost = result.get("cost", None)
|
|
148
148
|
usage = result.get("usage", {})
|
|
149
149
|
|
|
150
|
+
if isinstance(usage, (int, float)):
|
|
151
|
+
usage = {"total_tokens": usage}
|
|
152
|
+
|
|
150
153
|
span.set_attributes(
|
|
151
154
|
attributes={"total": cost},
|
|
152
155
|
namespace="metrics.unit.costs",
|
|
@@ -240,6 +243,9 @@ class instrument:
|
|
|
240
243
|
cost = result.get("cost", None)
|
|
241
244
|
usage = result.get("usage", {})
|
|
242
245
|
|
|
246
|
+
if isinstance(usage, (int, float)):
|
|
247
|
+
usage = {"total_tokens": usage}
|
|
248
|
+
|
|
243
249
|
span.set_attributes(
|
|
244
250
|
attributes={"total": cost},
|
|
245
251
|
namespace="metrics.unit.costs",
|
agenta/sdk/tracing/attributes.py
CHANGED
|
@@ -134,48 +134,3 @@ def serialize(
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
return _attributes
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
"""
|
|
140
|
-
def _decode_key(namespace: Optional[str] = None, key: str = "") -> str:
|
|
141
|
-
if namespace is None:
|
|
142
|
-
return key
|
|
143
|
-
|
|
144
|
-
return key.replace(f"ag.{namespace}.", "")
|
|
145
|
-
"""
|
|
146
|
-
|
|
147
|
-
"""
|
|
148
|
-
def _decode_value(value: Attribute) -> Any:
|
|
149
|
-
if isinstance(value, (int, float, bool, bytes)):
|
|
150
|
-
return value
|
|
151
|
-
|
|
152
|
-
if isinstance(value, str):
|
|
153
|
-
if value == "@ag.type=none:":
|
|
154
|
-
return None
|
|
155
|
-
|
|
156
|
-
if value.startswith("@ag.type=json:"):
|
|
157
|
-
encoded = value[len("@ag.type=json:") :]
|
|
158
|
-
value = loads(encoded)
|
|
159
|
-
return value
|
|
160
|
-
|
|
161
|
-
return value
|
|
162
|
-
|
|
163
|
-
return value
|
|
164
|
-
"""
|
|
165
|
-
|
|
166
|
-
"""
|
|
167
|
-
def deserialize(
|
|
168
|
-
*,
|
|
169
|
-
namespace: str,
|
|
170
|
-
attributes: Dict[str, Any],
|
|
171
|
-
max_depth: Optional[int] = None,
|
|
172
|
-
) -> Dict[str, Any]:
|
|
173
|
-
if not isinstance(attributes, dict):
|
|
174
|
-
return {}
|
|
175
|
-
|
|
176
|
-
return {
|
|
177
|
-
_decode_key(namespace, key): _decode_value(value)
|
|
178
|
-
for key, value in attributes
|
|
179
|
-
if key != _decode_key(namespace, key)
|
|
180
|
-
}
|
|
181
|
-
"""
|
|
@@ -1,25 +1,29 @@
|
|
|
1
|
-
from typing import Literal
|
|
2
|
-
|
|
3
1
|
from opentelemetry.trace import SpanKind
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
from re import fullmatch
|
|
6
|
+
|
|
7
|
+
_PATTERN = r"[A-Za-z0-9._-]+"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def is_valid_attribute_key(string):
|
|
11
|
+
return bool(fullmatch(_PATTERN, string))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Reference(str, Enum):
|
|
15
|
+
#
|
|
16
|
+
VARIANT_ID = "variant.id"
|
|
17
|
+
VARIANT_SLUG = "variant.slug"
|
|
18
|
+
VARIANT_VERSION = "variant.version"
|
|
19
|
+
#
|
|
20
|
+
ENVIRONMENT_ID = "environment.id"
|
|
21
|
+
ENVIRONMENT_SLUG = "environment.slug"
|
|
22
|
+
ENVIRONMENT_VERSION = "environment.version"
|
|
23
|
+
#
|
|
24
|
+
APPLICATION_ID = "application.id"
|
|
25
|
+
APPLICATION_SLUG = "application.slug"
|
|
26
|
+
#
|
|
23
27
|
|
|
24
28
|
|
|
25
29
|
def parse_span_kind(type: str) -> SpanKind:
|
agenta/sdk/tracing/exporters.py
CHANGED
agenta/sdk/tracing/inline.py
CHANGED
|
@@ -131,14 +131,6 @@ AttributeValueType = Any
|
|
|
131
131
|
Attributes = Dict[str, AttributeValueType]
|
|
132
132
|
|
|
133
133
|
|
|
134
|
-
class AttributesDTO(DisplayBase):
|
|
135
|
-
data: Optional[Attributes] = None
|
|
136
|
-
metrics: Optional[Attributes] = None
|
|
137
|
-
meta: Optional[Attributes] = None
|
|
138
|
-
tags: Optional[Attributes] = None
|
|
139
|
-
semconv: Optional[Attributes] = None
|
|
140
|
-
|
|
141
|
-
|
|
142
134
|
class TreeType(Enum):
|
|
143
135
|
# --- VARIANTS --- #
|
|
144
136
|
INVOCATION = "invocation"
|
|
@@ -242,7 +234,7 @@ class OTelExtraDTO(DisplayBase):
|
|
|
242
234
|
class SpanDTO(DisplayBase):
|
|
243
235
|
scope: ProjectScopeDTO
|
|
244
236
|
|
|
245
|
-
lifecycle: LifecycleDTO
|
|
237
|
+
lifecycle: Optional[LifecycleDTO] = None
|
|
246
238
|
|
|
247
239
|
root: RootDTO
|
|
248
240
|
tree: TreeDTO
|
|
@@ -266,29 +258,6 @@ class SpanDTO(DisplayBase):
|
|
|
266
258
|
nodes: Optional[Dict[str, Union["SpanDTO", List["SpanDTO"]]]] = None
|
|
267
259
|
|
|
268
260
|
|
|
269
|
-
class SpanCreateDTO(DisplayBase):
|
|
270
|
-
scope: ProjectScopeDTO
|
|
271
|
-
|
|
272
|
-
root: RootDTO
|
|
273
|
-
tree: TreeDTO
|
|
274
|
-
node: NodeDTO
|
|
275
|
-
|
|
276
|
-
parent: Optional[ParentDTO] = None
|
|
277
|
-
|
|
278
|
-
time: TimeDTO
|
|
279
|
-
status: StatusDTO
|
|
280
|
-
|
|
281
|
-
data: Optional[Data] = None
|
|
282
|
-
metrics: Optional[Metrics] = None
|
|
283
|
-
meta: Optional[Metadata] = None
|
|
284
|
-
tags: Optional[Tags] = None
|
|
285
|
-
refs: Optional[Refs] = None
|
|
286
|
-
|
|
287
|
-
links: Optional[List[LinkDTO]] = None
|
|
288
|
-
|
|
289
|
-
otel: Optional[OTelExtraDTO] = None
|
|
290
|
-
|
|
291
|
-
|
|
292
261
|
class OTelSpanDTO(DisplayBase):
|
|
293
262
|
context: OTelContextDTO
|
|
294
263
|
|
|
@@ -321,20 +290,20 @@ from typing import List, Dict, OrderedDict
|
|
|
321
290
|
|
|
322
291
|
|
|
323
292
|
def parse_span_dtos_to_span_idx(
|
|
324
|
-
span_dtos: List[
|
|
325
|
-
) -> Dict[str,
|
|
293
|
+
span_dtos: List[SpanDTO],
|
|
294
|
+
) -> Dict[str, SpanDTO]:
|
|
326
295
|
span_idx = {span_dto.node.id: span_dto for span_dto in span_dtos}
|
|
327
296
|
|
|
328
297
|
return span_idx
|
|
329
298
|
|
|
330
299
|
|
|
331
300
|
def parse_span_idx_to_span_id_tree(
|
|
332
|
-
span_idx: Dict[str,
|
|
301
|
+
span_idx: Dict[str, SpanDTO],
|
|
333
302
|
) -> OrderedDict:
|
|
334
303
|
span_id_tree = OrderedDict()
|
|
335
304
|
index = {}
|
|
336
305
|
|
|
337
|
-
def push(span_dto:
|
|
306
|
+
def push(span_dto: SpanDTO) -> None:
|
|
338
307
|
if span_dto.parent is None:
|
|
339
308
|
span_id_tree[span_dto.node.id] = OrderedDict()
|
|
340
309
|
index[span_dto.node.id] = span_id_tree[span_dto.node.id]
|
|
@@ -350,15 +319,15 @@ def parse_span_idx_to_span_id_tree(
|
|
|
350
319
|
|
|
351
320
|
def cumulate_costs(
|
|
352
321
|
spans_id_tree: OrderedDict,
|
|
353
|
-
spans_idx: Dict[str,
|
|
322
|
+
spans_idx: Dict[str, SpanDTO],
|
|
354
323
|
) -> None:
|
|
355
|
-
def _get_unit(span:
|
|
324
|
+
def _get_unit(span: SpanDTO):
|
|
356
325
|
if span.metrics is not None:
|
|
357
326
|
return span.metrics.get("unit.costs.total", 0.0)
|
|
358
327
|
|
|
359
328
|
return 0.0
|
|
360
329
|
|
|
361
|
-
def _get_acc(span:
|
|
330
|
+
def _get_acc(span: SpanDTO):
|
|
362
331
|
if span.metrics is not None:
|
|
363
332
|
return span.metrics.get("acc.costs.total", 0.0)
|
|
364
333
|
|
|
@@ -367,7 +336,7 @@ def cumulate_costs(
|
|
|
367
336
|
def _acc(a: float, b: float):
|
|
368
337
|
return a + b
|
|
369
338
|
|
|
370
|
-
def _set(span:
|
|
339
|
+
def _set(span: SpanDTO, cost: float):
|
|
371
340
|
if span.metrics is None:
|
|
372
341
|
span.metrics = {}
|
|
373
342
|
|
|
@@ -381,7 +350,7 @@ def cumulate_tokens(
|
|
|
381
350
|
spans_id_tree: OrderedDict,
|
|
382
351
|
spans_idx: Dict[str, dict],
|
|
383
352
|
) -> None:
|
|
384
|
-
def _get_unit(span:
|
|
353
|
+
def _get_unit(span: SpanDTO):
|
|
385
354
|
_tokens = {
|
|
386
355
|
"prompt": 0.0,
|
|
387
356
|
"completion": 0.0,
|
|
@@ -397,7 +366,7 @@ def cumulate_tokens(
|
|
|
397
366
|
|
|
398
367
|
return _tokens
|
|
399
368
|
|
|
400
|
-
def _get_acc(span:
|
|
369
|
+
def _get_acc(span: SpanDTO):
|
|
401
370
|
_tokens = {
|
|
402
371
|
"prompt": 0.0,
|
|
403
372
|
"completion": 0.0,
|
|
@@ -420,7 +389,7 @@ def cumulate_tokens(
|
|
|
420
389
|
"total": a.get("total", 0.0) + b.get("total", 0.0),
|
|
421
390
|
}
|
|
422
391
|
|
|
423
|
-
def _set(span:
|
|
392
|
+
def _set(span: SpanDTO, tokens: dict):
|
|
424
393
|
if span.metrics is None:
|
|
425
394
|
span.metrics = {}
|
|
426
395
|
|
|
@@ -442,7 +411,7 @@ def cumulate_tokens(
|
|
|
442
411
|
|
|
443
412
|
def _cumulate_tree_dfs(
|
|
444
413
|
spans_id_tree: OrderedDict,
|
|
445
|
-
spans_idx: Dict[str,
|
|
414
|
+
spans_idx: Dict[str, SpanDTO],
|
|
446
415
|
get_unit_metric,
|
|
447
416
|
get_acc_metric,
|
|
448
417
|
accumulate_metric,
|
|
@@ -1032,7 +1001,7 @@ def parse_inline_trace(
|
|
|
1032
1001
|
###############################################
|
|
1033
1002
|
### services.observability.service.ingest() ###
|
|
1034
1003
|
### --------------------------------------- ###
|
|
1035
|
-
|
|
1004
|
+
calculate_costs(span_idx)
|
|
1036
1005
|
cumulate_costs(span_id_tree, span_idx)
|
|
1037
1006
|
cumulate_tokens(span_id_tree, span_idx)
|
|
1038
1007
|
### --------------------------------------- ###
|
|
@@ -1254,7 +1223,7 @@ def _parse_to_legacy_span(span: SpanDTO) -> CreateSpan:
|
|
|
1254
1223
|
),
|
|
1255
1224
|
#
|
|
1256
1225
|
app_id=(
|
|
1257
|
-
span.refs.get("
|
|
1226
|
+
span.refs.get("application.id", "missing-app-id")
|
|
1258
1227
|
if span.refs
|
|
1259
1228
|
else "missing-app-id"
|
|
1260
1229
|
),
|
|
@@ -1271,7 +1240,7 @@ def _parse_to_legacy_span(span: SpanDTO) -> CreateSpan:
|
|
|
1271
1240
|
return legacy_span
|
|
1272
1241
|
|
|
1273
1242
|
|
|
1274
|
-
|
|
1243
|
+
TYPES_WITH_COSTS = [
|
|
1275
1244
|
"embedding",
|
|
1276
1245
|
"query",
|
|
1277
1246
|
"completion",
|
|
@@ -1280,9 +1249,14 @@ PAYING_TYPES = [
|
|
|
1280
1249
|
]
|
|
1281
1250
|
|
|
1282
1251
|
|
|
1283
|
-
def
|
|
1252
|
+
def calculate_costs(span_idx: Dict[str, SpanDTO]):
|
|
1284
1253
|
for span in span_idx.values():
|
|
1285
|
-
if
|
|
1254
|
+
if (
|
|
1255
|
+
span.node.type
|
|
1256
|
+
and span.node.type.name.lower() in TYPES_WITH_COSTS
|
|
1257
|
+
and span.meta
|
|
1258
|
+
and span.metrics
|
|
1259
|
+
):
|
|
1286
1260
|
try:
|
|
1287
1261
|
costs = cost_calculator.cost_per_token(
|
|
1288
1262
|
model=span.meta.get("response.model"),
|
agenta/sdk/tracing/processors.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
from typing import Optional,
|
|
1
|
+
from typing import Optional, Dict
|
|
2
|
+
from traceback import format_exc
|
|
2
3
|
|
|
3
4
|
from opentelemetry.context import Context
|
|
4
5
|
from opentelemetry.sdk.trace import Span
|
|
@@ -10,6 +11,8 @@ from opentelemetry.sdk.trace.export import (
|
|
|
10
11
|
_DEFAULT_MAX_QUEUE_SIZE,
|
|
11
12
|
)
|
|
12
13
|
|
|
14
|
+
from agenta.sdk.utils.logging import log
|
|
15
|
+
|
|
13
16
|
# LOAD CONTEXT, HERE
|
|
14
17
|
|
|
15
18
|
|
|
@@ -28,7 +31,7 @@ class TraceProcessor(BatchSpanProcessor):
|
|
|
28
31
|
_DEFAULT_MAX_QUEUE_SIZE,
|
|
29
32
|
60 * 60 * 1000, # 1 hour
|
|
30
33
|
_DEFAULT_MAX_QUEUE_SIZE,
|
|
31
|
-
|
|
34
|
+
500, # < 1 second (0.5 seconds)
|
|
32
35
|
)
|
|
33
36
|
|
|
34
37
|
self._registry = dict()
|
|
@@ -54,6 +57,14 @@ class TraceProcessor(BatchSpanProcessor):
|
|
|
54
57
|
if self.is_ready(span.get_span_context().trace_id):
|
|
55
58
|
self.force_flush()
|
|
56
59
|
|
|
60
|
+
def force_flush(self, timeout_millis: int = None) -> bool:
|
|
61
|
+
ret = super().force_flush(timeout_millis)
|
|
62
|
+
|
|
63
|
+
if not ret:
|
|
64
|
+
log.error("--------------------------------------------")
|
|
65
|
+
log.error("Agenta SDK - skipping export due to timeout.")
|
|
66
|
+
log.error("--------------------------------------------")
|
|
67
|
+
|
|
57
68
|
def is_ready(self, trace_id: Optional[int] = None) -> bool:
|
|
58
69
|
is_ready = not len(self._registry.get(trace_id, {}))
|
|
59
70
|
|
agenta/sdk/tracing/tracing.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from typing import Optional, Any, Dict
|
|
2
|
+
from enum import Enum
|
|
2
3
|
|
|
3
4
|
from httpx import get as check
|
|
4
5
|
|
|
@@ -13,15 +14,16 @@ from opentelemetry.sdk.trace import Span, Tracer, TracerProvider
|
|
|
13
14
|
from opentelemetry.sdk.resources import Resource
|
|
14
15
|
|
|
15
16
|
from agenta.sdk.utils.singleton import Singleton
|
|
16
|
-
from agenta.sdk.utils.exceptions import suppress
|
|
17
|
+
from agenta.sdk.utils.exceptions import suppress
|
|
17
18
|
from agenta.sdk.utils.logging import log
|
|
18
19
|
|
|
19
20
|
from agenta.sdk.tracing.processors import TraceProcessor
|
|
20
21
|
from agenta.sdk.tracing.exporters import ConsoleExporter, InlineExporter, OTLPExporter
|
|
21
22
|
from agenta.sdk.tracing.spans import CustomSpan
|
|
22
|
-
from agenta.sdk.tracing.context import tracing_context
|
|
23
23
|
from agenta.sdk.tracing.inline import parse_inline_trace
|
|
24
24
|
|
|
25
|
+
from agenta.sdk.tracing.conventions import Reference, is_valid_attribute_key
|
|
26
|
+
|
|
25
27
|
|
|
26
28
|
class Tracing(metaclass=Singleton):
|
|
27
29
|
VERSION = "0.1.0"
|
|
@@ -74,7 +76,7 @@ class Tracing(metaclass=Singleton):
|
|
|
74
76
|
if api_key:
|
|
75
77
|
self.headers.update(**{"Authorization": self.api_key})
|
|
76
78
|
# REFERENCES
|
|
77
|
-
self.references = {"
|
|
79
|
+
self.references = {"application.id": app_id}
|
|
78
80
|
|
|
79
81
|
# TRACER PROVIDER
|
|
80
82
|
self.tracer_provider = TracerProvider(
|
|
@@ -120,10 +122,13 @@ class Tracing(metaclass=Singleton):
|
|
|
120
122
|
def get_current_span(
|
|
121
123
|
self,
|
|
122
124
|
):
|
|
123
|
-
_span =
|
|
125
|
+
_span = None
|
|
126
|
+
|
|
127
|
+
with suppress():
|
|
128
|
+
_span = get_current_span()
|
|
124
129
|
|
|
125
|
-
|
|
126
|
-
|
|
130
|
+
if _span.is_recording():
|
|
131
|
+
return CustomSpan(_span)
|
|
127
132
|
|
|
128
133
|
return _span
|
|
129
134
|
|
|
@@ -132,39 +137,89 @@ class Tracing(metaclass=Singleton):
|
|
|
132
137
|
attributes: Dict[str, Any],
|
|
133
138
|
span: Optional[Span] = None,
|
|
134
139
|
):
|
|
135
|
-
|
|
136
|
-
span
|
|
140
|
+
with suppress():
|
|
141
|
+
if span is None:
|
|
142
|
+
span = self.get_current_span()
|
|
143
|
+
|
|
144
|
+
span.set_attributes(attributes={"internals": attributes}, namespace="data")
|
|
145
|
+
|
|
146
|
+
def store_refs(
|
|
147
|
+
self,
|
|
148
|
+
refs: Dict[str, str],
|
|
149
|
+
span: Optional[Span] = None,
|
|
150
|
+
):
|
|
151
|
+
with suppress():
|
|
152
|
+
if span is None:
|
|
153
|
+
span = self.get_current_span()
|
|
154
|
+
|
|
155
|
+
for key in refs.keys():
|
|
156
|
+
if key in Reference:
|
|
157
|
+
# ADD REFERENCE TO THIS SPAN
|
|
158
|
+
span.set_attribute(
|
|
159
|
+
key.value if isinstance(key, Enum) else key,
|
|
160
|
+
refs[key],
|
|
161
|
+
namespace="refs",
|
|
162
|
+
)
|
|
163
|
+
# AND TO ALL SPANS CREATED AFTER THIS ONE
|
|
164
|
+
self.references[key] = refs[key]
|
|
165
|
+
# TODO: THIS SHOULD BE REPLACED BY A TRACE CONTEXT !!!
|
|
166
|
+
|
|
167
|
+
def store_meta(
|
|
168
|
+
self,
|
|
169
|
+
meta: Dict[str, Any],
|
|
170
|
+
span: Optional[Span] = None,
|
|
171
|
+
):
|
|
172
|
+
with suppress():
|
|
173
|
+
if span is None:
|
|
174
|
+
span = self.get_current_span()
|
|
175
|
+
|
|
176
|
+
for key in meta.keys():
|
|
177
|
+
if is_valid_attribute_key(key):
|
|
178
|
+
span.set_attribute(key, meta[key], namespace="meta")
|
|
137
179
|
|
|
138
|
-
|
|
180
|
+
def store_metrics(
|
|
181
|
+
self,
|
|
182
|
+
metrics: Dict[str, Any],
|
|
183
|
+
span: Optional[Span] = None,
|
|
184
|
+
):
|
|
185
|
+
with suppress():
|
|
186
|
+
if span is None:
|
|
187
|
+
span = self.get_current_span()
|
|
188
|
+
|
|
189
|
+
for key in metrics.keys():
|
|
190
|
+
if is_valid_attribute_key(key):
|
|
191
|
+
span.set_attribute(key, metrics[key], namespace="metrics")
|
|
139
192
|
|
|
140
193
|
def is_inline_trace_ready(
|
|
141
194
|
self,
|
|
142
|
-
trace_id: int,
|
|
195
|
+
trace_id: Optional[int] = None,
|
|
143
196
|
) -> bool:
|
|
144
|
-
is_ready =
|
|
197
|
+
is_ready = True
|
|
198
|
+
|
|
199
|
+
with suppress():
|
|
200
|
+
if trace_id is not None:
|
|
201
|
+
is_ready = self.inline.is_ready(trace_id)
|
|
145
202
|
|
|
146
203
|
return is_ready
|
|
147
204
|
|
|
148
205
|
def get_inline_trace(
|
|
149
206
|
self,
|
|
150
|
-
trace_id: int,
|
|
207
|
+
trace_id: Optional[int] = None,
|
|
151
208
|
) -> Dict[str, Any]:
|
|
152
|
-
|
|
153
|
-
return {}
|
|
154
|
-
|
|
155
|
-
is_ready = self.inline.is_ready(trace_id)
|
|
156
|
-
|
|
157
|
-
if is_ready is False:
|
|
158
|
-
return {}
|
|
209
|
+
_inline_trace = {}
|
|
159
210
|
|
|
160
|
-
|
|
211
|
+
with suppress():
|
|
212
|
+
is_ready = self.inline.is_ready(trace_id)
|
|
161
213
|
|
|
162
|
-
|
|
163
|
-
|
|
214
|
+
if is_ready is True:
|
|
215
|
+
otel_spans = self.inline.fetch(trace_id)
|
|
164
216
|
|
|
165
|
-
|
|
217
|
+
if otel_spans:
|
|
218
|
+
_inline_trace = parse_inline_trace(
|
|
219
|
+
self.project_id or self.app_id, otel_spans
|
|
220
|
+
)
|
|
166
221
|
|
|
167
|
-
return
|
|
222
|
+
return _inline_trace
|
|
168
223
|
|
|
169
224
|
|
|
170
225
|
def get_tracer(tracing: Tracing) -> Tracer:
|
agenta/sdk/utils/exceptions.py
CHANGED
|
@@ -12,8 +12,11 @@ class suppress(AbstractContextManager):
|
|
|
12
12
|
|
|
13
13
|
def __exit__(self, exc_type, exc_value, exc_tb):
|
|
14
14
|
if exc_type is None:
|
|
15
|
-
return
|
|
15
|
+
return True
|
|
16
16
|
else:
|
|
17
|
-
|
|
18
|
-
log.error(
|
|
19
|
-
|
|
17
|
+
log.error("-------------------------------------------------")
|
|
18
|
+
log.error("Agenta SDK - suppressing tracing exception below:")
|
|
19
|
+
log.error("-------------------------------------------------")
|
|
20
|
+
log.error(format_exc().strip("\n"))
|
|
21
|
+
log.error("-------------------------------------------------")
|
|
22
|
+
return True
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
agenta/__init__.py,sha256=
|
|
1
|
+
agenta/__init__.py,sha256=6NgtqH14bL5M25Kqy2F8KueChz1snciKiIxho__i_UI,970
|
|
2
2
|
agenta/cli/evaluation_commands.py,sha256=fs6492tprPId9p8eGO02Xy-NCBm2RZNJLZWcUxugwd8,474
|
|
3
3
|
agenta/cli/helper.py,sha256=vRxHyeNaltzNIGrfU2vO0H28_rXDzx9QqIZ_S-W6zL4,6212
|
|
4
4
|
agenta/cli/main.py,sha256=Wz0ODhoeKK3Qg_CFUhu6D909szk05tc8ZVBB6H1-w7k,9763
|
|
@@ -132,8 +132,8 @@ agenta/docker/docker-assets/entrypoint.sh,sha256=29XK8VQjQsx4hN2j-4JDy-6kQb5y4LC
|
|
|
132
132
|
agenta/docker/docker-assets/lambda_function.py,sha256=h4UZSSfqwpfsCgERv6frqwm_4JrYu9rLz3I-LxCfeEg,83
|
|
133
133
|
agenta/docker/docker-assets/main.py,sha256=7MI-21n81U7N7A0GxebNi0cmGWtJKcR2sPB6FcH2QfA,251
|
|
134
134
|
agenta/docker/docker_utils.py,sha256=kO1q2_IR0fEAo4M-2Pt_v-zC7GxxnkLogjKFhU869Ps,3555
|
|
135
|
-
agenta/sdk/__init__.py,sha256=
|
|
136
|
-
agenta/sdk/agenta_init.py,sha256=
|
|
135
|
+
agenta/sdk/__init__.py,sha256=IopYEonqvpdGXsAYh2wQ4Ai_2YzsY7aF88wTzrclV4M,1208
|
|
136
|
+
agenta/sdk/agenta_init.py,sha256=hBE78BIu6QFfvaxWY2x7Y7EXAFKx6TSPEtEj2S6qWNU,10606
|
|
137
137
|
agenta/sdk/assets.py,sha256=Zv4i8MVUSB3jMODQon1mzJtYxuntmrCNjLGk8f-2fls,2856
|
|
138
138
|
agenta/sdk/client.py,sha256=trKyBOYFZRk0v5Eptxvh87yPf50Y9CqY6Qgv4Fy-VH4,2142
|
|
139
139
|
agenta/sdk/config_manager.py,sha256=HFOJpJKBkhlA0C-KPuxb4-bHNZeZqdpmx_beoX4lQw8,7997
|
|
@@ -141,25 +141,25 @@ agenta/sdk/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
|
141
141
|
agenta/sdk/context/routing.py,sha256=gOoOM88hSjIjzQ3ni68TjUoq7WtwSH3kB07YjCYvW2c,631
|
|
142
142
|
agenta/sdk/context/tracing.py,sha256=UmmW15UFFsvxS0myS6aD9wBk5iNepNlQi4tEQ_ejfYM,96
|
|
143
143
|
agenta/sdk/decorators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
144
|
-
agenta/sdk/decorators/routing.py,sha256=
|
|
145
|
-
agenta/sdk/decorators/tracing.py,sha256
|
|
144
|
+
agenta/sdk/decorators/routing.py,sha256=L3_bYJ254x6uB4d8_TK47jKIsHrz4kibf3Dlty9UHQM,36026
|
|
145
|
+
agenta/sdk/decorators/tracing.py,sha256=-A1GjhPs9OicDtXidtxAEGnUJRyuzZR1oHA95rsNrzw,11457
|
|
146
146
|
agenta/sdk/litellm/__init__.py,sha256=Bpz1gfHQc0MN1yolWcjifLWznv6GjHggvRGQSpxpihM,37
|
|
147
147
|
agenta/sdk/litellm/litellm.py,sha256=j4WyRTQdxLkvelaPm5BfUbaUxkbQXDhyr3yp9yXo1RQ,8289
|
|
148
148
|
agenta/sdk/router.py,sha256=mOguvtOwl2wmyAgOuWTsf98pQwpNiUILKIo67W_hR3A,119
|
|
149
149
|
agenta/sdk/tracing/__init__.py,sha256=rQNe5-zT5Kt7_CDhq-lnUIi1EYTBVzVf_MbfcIxVD98,41
|
|
150
|
-
agenta/sdk/tracing/attributes.py,sha256=
|
|
150
|
+
agenta/sdk/tracing/attributes.py,sha256=eYVzsAt_2ekDCO_RQ7VrZHuySftFbcRPKaf9lEvXx0E,3815
|
|
151
151
|
agenta/sdk/tracing/context.py,sha256=KDQYjRcmbpb6e0xEuX-bAQGhEjwx4H2nwybRPOKCDjo,578
|
|
152
|
-
agenta/sdk/tracing/conventions.py,sha256=
|
|
153
|
-
agenta/sdk/tracing/exporters.py,sha256=
|
|
154
|
-
agenta/sdk/tracing/inline.py,sha256=
|
|
155
|
-
agenta/sdk/tracing/processors.py,sha256=
|
|
152
|
+
agenta/sdk/tracing/conventions.py,sha256=W7-FVjLjnBGiY9cvxFzW4tlsdFwW9l5LLGm8AgMynmM,938
|
|
153
|
+
agenta/sdk/tracing/exporters.py,sha256=hTGbdkuH1rIqT7aRsSIYolQPCq2MxmEfT9IGBn20mRU,1370
|
|
154
|
+
agenta/sdk/tracing/inline.py,sha256=OtYkGMO2XKdLH7t2vqVqteLs8zQCGyM93sCIU-xYD8Y,35163
|
|
155
|
+
agenta/sdk/tracing/processors.py,sha256=PpCJcyhZdr_hNjA_QlM6jtTZj6neUMdA_C5rnx97BfM,2390
|
|
156
156
|
agenta/sdk/tracing/spans.py,sha256=AnQuuyuCGST6n_He4SF5WdrtMts9JlE8v6rVRdm2rRg,3570
|
|
157
|
-
agenta/sdk/tracing/tracing.py,sha256=
|
|
157
|
+
agenta/sdk/tracing/tracing.py,sha256=XIBYRAsQ6bb0hkcybKJNP0uVaPl3dE4NcTYzwlwAOOA,6942
|
|
158
158
|
agenta/sdk/types.py,sha256=B7C7Jpeq0CpmLwmN1dmpggJsZX8WpxyyM42PkdSsx3s,5669
|
|
159
159
|
agenta/sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
160
160
|
agenta/sdk/utils/costs.py,sha256=i8C7ud__pThLS55XkN4YW8czXtGeXr2mx7jjcOFeiXg,5955
|
|
161
161
|
agenta/sdk/utils/debug.py,sha256=DxiCAeXxxrcEZT2CjlNA6BMvujGP4nzQ-rfb-_mLMck,2114
|
|
162
|
-
agenta/sdk/utils/exceptions.py,sha256=
|
|
162
|
+
agenta/sdk/utils/exceptions.py,sha256=joC46DnUE3dg1XOZv_k1PKYxKzRuUPS0Di1TTmGbbH0,731
|
|
163
163
|
agenta/sdk/utils/globals.py,sha256=2HhyzWn55BbYNCZ3rT8dAxk1GGXuGQPbtq_THjaHbBw,372
|
|
164
164
|
agenta/sdk/utils/logging.py,sha256=FKzAO5eHjR_qvpEnc4tKXUA6WftmwdwYwuJK6CbSc84,379
|
|
165
165
|
agenta/sdk/utils/preinit.py,sha256=YlJL7RLfel0R7DFp-jK7OV-z4ZIQJM0oupYlk7g8b5o,1278
|
|
@@ -179,7 +179,7 @@ agenta/templates/simple_prompt/app.py,sha256=kODgF6lhzsaJPdgL5b21bUki6jkvqjWZzWR
|
|
|
179
179
|
agenta/templates/simple_prompt/env.example,sha256=g9AE5bYcGPpxawXMJ96gh8oenEPCHTabsiOnfQo3c5k,70
|
|
180
180
|
agenta/templates/simple_prompt/requirements.txt,sha256=ywRglRy7pPkw8bljmMEJJ4aOOQKrt9FGKULZ-DGkoBU,23
|
|
181
181
|
agenta/templates/simple_prompt/template.toml,sha256=DQBtRrF4GU8LBEXOZ-GGuINXMQDKGTEG5y37tnvIUIE,60
|
|
182
|
-
agenta-0.27.
|
|
183
|
-
agenta-0.27.
|
|
184
|
-
agenta-0.27.
|
|
185
|
-
agenta-0.27.
|
|
182
|
+
agenta-0.27.0a2.dist-info/METADATA,sha256=ApO4L8qDn3H-cS4dfvbP2g5yyieP1Rc-rkUfWsdfRn0,31738
|
|
183
|
+
agenta-0.27.0a2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
184
|
+
agenta-0.27.0a2.dist-info/entry_points.txt,sha256=PDiu8_8AsL7ibU9v4iNoOKR1S7F2rdxjlEprjM9QOgo,46
|
|
185
|
+
agenta-0.27.0a2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|