raindrop-ai 0.0.29__py3-none-any.whl → 0.0.31__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.
raindrop/analytics.py
CHANGED
|
@@ -29,8 +29,18 @@ import weakref
|
|
|
29
29
|
import urllib.parse
|
|
30
30
|
|
|
31
31
|
from traceloop.sdk import Traceloop
|
|
32
|
-
from traceloop.sdk.tracing.tracing import
|
|
32
|
+
from traceloop.sdk.tracing.tracing import (
|
|
33
|
+
TracerWrapper,
|
|
34
|
+
get_chained_entity_path,
|
|
35
|
+
set_entity_path,
|
|
36
|
+
)
|
|
33
37
|
from opentelemetry.trace import get_current_span
|
|
38
|
+
from opentelemetry import trace
|
|
39
|
+
from opentelemetry import context as context_api
|
|
40
|
+
from opentelemetry.semconv_ai import SpanAttributes
|
|
41
|
+
from opentelemetry.trace.status import Status, StatusCode
|
|
42
|
+
from traceloop.sdk.utils.json_encoder import JSONEncoder
|
|
43
|
+
from traceloop.sdk.tracing.context_manager import get_tracer
|
|
34
44
|
from traceloop.sdk.decorators import (
|
|
35
45
|
task as tlp_task,
|
|
36
46
|
workflow as tlp_workflow,
|
|
@@ -38,6 +48,26 @@ from traceloop.sdk.decorators import (
|
|
|
38
48
|
F,
|
|
39
49
|
)
|
|
40
50
|
|
|
51
|
+
__all__ = [
|
|
52
|
+
# Configuration functions
|
|
53
|
+
"set_debug_logs",
|
|
54
|
+
"set_redact_pii",
|
|
55
|
+
"init",
|
|
56
|
+
"identify",
|
|
57
|
+
"track_ai",
|
|
58
|
+
"track_signal",
|
|
59
|
+
"begin",
|
|
60
|
+
"resume_interaction",
|
|
61
|
+
"interaction",
|
|
62
|
+
"task",
|
|
63
|
+
"tool",
|
|
64
|
+
"task_span",
|
|
65
|
+
"tool_span",
|
|
66
|
+
"set_span_properties",
|
|
67
|
+
"flush",
|
|
68
|
+
"shutdown",
|
|
69
|
+
]
|
|
70
|
+
|
|
41
71
|
|
|
42
72
|
# Configure logging
|
|
43
73
|
logging.basicConfig(
|
|
@@ -293,6 +323,28 @@ def _get_size(event: dict[str, any]) -> int:
|
|
|
293
323
|
return 0
|
|
294
324
|
|
|
295
325
|
|
|
326
|
+
def _truncate_json_if_needed(json_str: str) -> str:
|
|
327
|
+
"""
|
|
328
|
+
Truncate JSON string if it exceeds OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT;
|
|
329
|
+
truncation may yield an invalid JSON string, which is expected for logging purposes.
|
|
330
|
+
"""
|
|
331
|
+
limit_str = os.getenv("OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT")
|
|
332
|
+
if limit_str:
|
|
333
|
+
try:
|
|
334
|
+
limit = int(limit_str)
|
|
335
|
+
if limit > 0 and len(json_str) > limit:
|
|
336
|
+
return json_str[:limit]
|
|
337
|
+
except ValueError:
|
|
338
|
+
pass
|
|
339
|
+
return json_str
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
def _should_send_prompts():
|
|
343
|
+
return (
|
|
344
|
+
os.getenv("TRACELOOP_TRACE_CONTENT") or "true"
|
|
345
|
+
).lower() == "true" or context_api.get_value("override_enable_content_tracing")
|
|
346
|
+
|
|
347
|
+
|
|
296
348
|
# Signal types - This is now defined in models.py
|
|
297
349
|
# SignalType = Literal["default", "feedback", "edit"]
|
|
298
350
|
|
|
@@ -552,6 +604,110 @@ def set_span_properties(properties: Dict[str, Any]) -> None:
|
|
|
552
604
|
Traceloop.set_association_properties(properties)
|
|
553
605
|
|
|
554
606
|
|
|
607
|
+
class TraceEntitySpan:
|
|
608
|
+
def __init__(self, span):
|
|
609
|
+
self._span = span
|
|
610
|
+
|
|
611
|
+
def record_input(self, data: Any) -> None:
|
|
612
|
+
if self._span and _should_send_prompts():
|
|
613
|
+
try:
|
|
614
|
+
json_input = json.dumps({"args": [data]}, cls=JSONEncoder)
|
|
615
|
+
truncated = _truncate_json_if_needed(json_input)
|
|
616
|
+
self._span.set_attribute(
|
|
617
|
+
SpanAttributes.TRACELOOP_ENTITY_INPUT, truncated
|
|
618
|
+
)
|
|
619
|
+
except TypeError as e:
|
|
620
|
+
logger.debug(f"[raindrop] Could not serialize input for span: {e}")
|
|
621
|
+
|
|
622
|
+
def record_output(self, data: Any) -> None:
|
|
623
|
+
if self._span and _should_send_prompts():
|
|
624
|
+
try:
|
|
625
|
+
json_output = json.dumps(data, cls=JSONEncoder)
|
|
626
|
+
truncated = _truncate_json_if_needed(json_output)
|
|
627
|
+
self._span.set_attribute(
|
|
628
|
+
SpanAttributes.TRACELOOP_ENTITY_OUTPUT, truncated
|
|
629
|
+
)
|
|
630
|
+
except TypeError as e:
|
|
631
|
+
logger.debug(f"[raindrop] Could not serialize output for span: {e}")
|
|
632
|
+
|
|
633
|
+
def set_properties(self, props: Dict[str, Any]) -> None:
|
|
634
|
+
if _tracing_enabled and props:
|
|
635
|
+
Traceloop.set_association_properties(props)
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
class _EntitySpanContext:
|
|
639
|
+
def __init__(self, kind: Literal["task", "tool"], name: str, version: int | None):
|
|
640
|
+
self._kind = kind
|
|
641
|
+
self._name = name
|
|
642
|
+
self._version = version
|
|
643
|
+
self._span = None
|
|
644
|
+
self._ctx_token = None
|
|
645
|
+
self._span_cm = None
|
|
646
|
+
self._helper = TraceEntitySpan(None)
|
|
647
|
+
|
|
648
|
+
# internal start/finish
|
|
649
|
+
def _start(self) -> None:
|
|
650
|
+
if not _tracing_enabled or not TracerWrapper.verify_initialized():
|
|
651
|
+
return
|
|
652
|
+
tlp_kind = (
|
|
653
|
+
TraceloopSpanKindValues.TASK
|
|
654
|
+
if self._kind == "task"
|
|
655
|
+
else TraceloopSpanKindValues.TOOL
|
|
656
|
+
)
|
|
657
|
+
span_name = f"{self._name}.{tlp_kind.value}"
|
|
658
|
+
with get_tracer() as tracer:
|
|
659
|
+
self._span_cm = tracer.start_as_current_span(span_name)
|
|
660
|
+
span = self._span_cm.__enter__()
|
|
661
|
+
|
|
662
|
+
if tlp_kind in [TraceloopSpanKindValues.TASK, TraceloopSpanKindValues.TOOL]:
|
|
663
|
+
entity_path = get_chained_entity_path(self._name)
|
|
664
|
+
set_entity_path(entity_path)
|
|
665
|
+
|
|
666
|
+
span.set_attribute(SpanAttributes.TRACELOOP_SPAN_KIND, tlp_kind.value)
|
|
667
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_NAME, self._name)
|
|
668
|
+
if self._version is not None:
|
|
669
|
+
span.set_attribute(SpanAttributes.TRACELOOP_ENTITY_VERSION, self._version)
|
|
670
|
+
|
|
671
|
+
self._span = span
|
|
672
|
+
self._helper = TraceEntitySpan(span)
|
|
673
|
+
|
|
674
|
+
def _end(self, exc_type, exc, tb) -> bool:
|
|
675
|
+
if not self._span:
|
|
676
|
+
return False
|
|
677
|
+
try:
|
|
678
|
+
if exc is not None:
|
|
679
|
+
self._span.set_status(Status(StatusCode.ERROR, str(exc)))
|
|
680
|
+
self._span.record_exception(exc)
|
|
681
|
+
return False
|
|
682
|
+
finally:
|
|
683
|
+
if self._span_cm is not None:
|
|
684
|
+
self._span_cm.__exit__(exc_type, exc, tb)
|
|
685
|
+
|
|
686
|
+
# sync
|
|
687
|
+
def __enter__(self) -> TraceEntitySpan:
|
|
688
|
+
self._start()
|
|
689
|
+
return self._helper
|
|
690
|
+
|
|
691
|
+
def __exit__(self, exc_type, exc, tb) -> bool:
|
|
692
|
+
return self._end(exc_type, exc, tb)
|
|
693
|
+
|
|
694
|
+
# async
|
|
695
|
+
async def __aenter__(self) -> TraceEntitySpan:
|
|
696
|
+
self._start()
|
|
697
|
+
return self._helper
|
|
698
|
+
|
|
699
|
+
async def __aexit__(self, exc_type, exc, tb) -> bool:
|
|
700
|
+
return self._end(exc_type, exc, tb)
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
def task_span(name: str, version: int | None = None) -> _EntitySpanContext:
|
|
704
|
+
return _EntitySpanContext("task", name, version)
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
def tool_span(name: str, version: int | None = None) -> _EntitySpanContext:
|
|
708
|
+
return _EntitySpanContext("tool", name, version)
|
|
709
|
+
|
|
710
|
+
|
|
555
711
|
def resume_interaction(event_id: str | None = None) -> Interaction:
|
|
556
712
|
"""Return an Interaction associated with the current trace or given event_id."""
|
|
557
713
|
|
raindrop/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
VERSION = "0.0.
|
|
1
|
+
VERSION = "0.0.31"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
raindrop/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
raindrop/analytics.py,sha256=
|
|
2
|
+
raindrop/analytics.py,sha256=XHCXHM-S92ZAgsigPrDovUDTSlHiLLfuIHHEq9wnpTY,24354
|
|
3
3
|
raindrop/interaction.py,sha256=1gYFj2-oEobLtG56RZw5de3RjYr0pCXg_NqYDGx32Uc,1896
|
|
4
4
|
raindrop/models.py,sha256=dEhwTtBEgwOOW_qaPEYugCLeOqvDXuBpEfi7vUANVK0,5361
|
|
5
5
|
raindrop/redact.py,sha256=rMNUoI90KxOY3d_zcHAr0TFD2yQ_CDgpDz-1XJLVmHs,7658
|
|
6
|
-
raindrop/version.py,sha256=
|
|
6
|
+
raindrop/version.py,sha256=g9PK7-EZQg9Xj85paKedV-EguQ1hpWMe5uKllKCG_QI,19
|
|
7
7
|
raindrop/well-known-names.json,sha256=9giJF6u6W1R0APW-Pf1dvNUU32OXQEoQ9CBQXSnA3ks,144403
|
|
8
|
-
raindrop_ai-0.0.
|
|
9
|
-
raindrop_ai-0.0.
|
|
10
|
-
raindrop_ai-0.0.
|
|
8
|
+
raindrop_ai-0.0.31.dist-info/METADATA,sha256=1ChjDAUZRU0R2kjK9RpwveWVefChGoRwm-bhdn1cctg,1269
|
|
9
|
+
raindrop_ai-0.0.31.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
10
|
+
raindrop_ai-0.0.31.dist-info/RECORD,,
|
|
File without changes
|