agenta 0.25.4a3__py3-none-any.whl → 0.25.4a4__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 (42) hide show
  1. agenta/__init__.py +7 -6
  2. agenta/client/backend/client.py +14 -22
  3. agenta/client/backend/core/http_client.py +15 -23
  4. agenta/client/backend/core/pydantic_utilities.py +0 -2
  5. agenta/sdk/__init__.py +6 -27
  6. agenta/sdk/agenta_init.py +26 -73
  7. agenta/sdk/config_manager.py +2 -2
  8. agenta/sdk/context.py +41 -0
  9. agenta/sdk/decorators/base.py +10 -0
  10. agenta/sdk/decorators/{routing.py → llm_entrypoint.py} +124 -137
  11. agenta/sdk/decorators/tracing.py +79 -247
  12. agenta/sdk/router.py +7 -0
  13. agenta/sdk/tracing/__init__.py +0 -1
  14. agenta/sdk/tracing/callbacks.py +187 -0
  15. agenta/sdk/tracing/llm_tracing.py +617 -0
  16. agenta/sdk/{utils/logging.py → tracing/logger.py} +5 -3
  17. agenta/sdk/tracing/tasks_manager.py +129 -0
  18. agenta/sdk/tracing/tracing_context.py +27 -0
  19. agenta/sdk/types.py +12 -0
  20. agenta/sdk/utils/debug.py +5 -5
  21. agenta/sdk/utils/globals.py +5 -3
  22. agenta/sdk/utils/{costs.py → helper/openai_cost.py} +0 -3
  23. {agenta-0.25.4a3.dist-info → agenta-0.25.4a4.dist-info}/METADATA +1 -5
  24. {agenta-0.25.4a3.dist-info → agenta-0.25.4a4.dist-info}/RECORD +26 -36
  25. agenta/sdk/context/__init__.py +0 -0
  26. agenta/sdk/context/routing.py +0 -25
  27. agenta/sdk/context/tracing.py +0 -3
  28. agenta/sdk/decorators/__init__.py +0 -0
  29. agenta/sdk/litellm/__init__.py +0 -1
  30. agenta/sdk/litellm/litellm.py +0 -277
  31. agenta/sdk/tracing/attributes.py +0 -181
  32. agenta/sdk/tracing/context.py +0 -21
  33. agenta/sdk/tracing/conventions.py +0 -43
  34. agenta/sdk/tracing/exporters.py +0 -53
  35. agenta/sdk/tracing/inline.py +0 -1305
  36. agenta/sdk/tracing/processors.py +0 -65
  37. agenta/sdk/tracing/spans.py +0 -124
  38. agenta/sdk/tracing/tracing.py +0 -174
  39. agenta/sdk/utils/exceptions.py +0 -19
  40. agenta/sdk/utils/singleton.py +0 -13
  41. {agenta-0.25.4a3.dist-info → agenta-0.25.4a4.dist-info}/WHEEL +0 -0
  42. {agenta-0.25.4a3.dist-info → agenta-0.25.4a4.dist-info}/entry_points.txt +0 -0
@@ -1,65 +0,0 @@
1
- from typing import Optional, Any, Dict
2
-
3
- from opentelemetry.context import Context
4
- from opentelemetry.sdk.trace import Span
5
- from opentelemetry.sdk.trace.export import (
6
- SpanExporter,
7
- ReadableSpan,
8
- BatchSpanProcessor,
9
- _DEFAULT_EXPORT_TIMEOUT_MILLIS,
10
- _DEFAULT_MAX_QUEUE_SIZE,
11
- )
12
-
13
- # LOAD CONTEXT, HERE
14
-
15
-
16
- class TraceProcessor(BatchSpanProcessor):
17
- def __init__(
18
- self,
19
- span_exporter: SpanExporter,
20
- references: Dict[str, str] = None,
21
- max_queue_size: int = None,
22
- schedule_delay_millis: float = None,
23
- max_export_batch_size: int = None,
24
- export_timeout_millis: float = None,
25
- ):
26
- super().__init__(
27
- span_exporter,
28
- _DEFAULT_MAX_QUEUE_SIZE,
29
- 60 * 60 * 1000, # 1 hour
30
- _DEFAULT_MAX_QUEUE_SIZE,
31
- _DEFAULT_EXPORT_TIMEOUT_MILLIS,
32
- )
33
-
34
- self._registry = dict()
35
- self._exporter = span_exporter
36
- self.references = references or dict()
37
-
38
- def on_start(self, span: Span, parent_context: Optional[Context] = None) -> None:
39
- # ADD LINKS FROM CONTEXT, HERE
40
-
41
- for key in self.references.keys():
42
- span.set_attribute(f"ag.refs.{key}", self.references[key])
43
-
44
- if span.context.trace_id not in self._registry:
45
- self._registry[span.context.trace_id] = dict()
46
-
47
- self._registry[span.context.trace_id][span.context.span_id] = True
48
-
49
- def on_end(self, span: ReadableSpan):
50
- super().on_end(span)
51
-
52
- del self._registry[span.context.trace_id][span.context.span_id]
53
-
54
- if self.is_ready(span.get_span_context().trace_id):
55
- self.force_flush()
56
-
57
- def is_ready(self, trace_id: Optional[int] = None) -> bool:
58
- is_ready = not len(self._registry.get(trace_id, {}))
59
-
60
- return is_ready
61
-
62
- def fetch(self, trace_id: Optional[int] = None) -> Dict[str, ReadableSpan]:
63
- trace = self._exporter.fetch(trace_id) # type: ignore
64
-
65
- return trace
@@ -1,124 +0,0 @@
1
- from typing import Optional, Union, Any, Dict
2
-
3
- from opentelemetry.trace import SpanContext
4
- from opentelemetry.trace.status import Status, StatusCode
5
- from opentelemetry.sdk.trace import Span
6
-
7
- from agenta.sdk.tracing.attributes import serialize
8
-
9
-
10
- class CustomSpan(Span): # INHERITANCE FOR TYPING ONLY
11
- def __init__(self, span: Span) -> None:
12
- super().__init__( # INHERITANCE FOR TYPING ONLY
13
- name=span.name,
14
- context=span.context,
15
- parent=span.parent,
16
- sampler=span._sampler,
17
- trace_config=span._trace_config,
18
- resource=span.resource,
19
- attributes=span.attributes,
20
- events=span.events,
21
- links=span.links,
22
- kind=span.kind,
23
- span_processor=span._span_processor,
24
- instrumentation_info=span.instrumentation_info,
25
- record_exception=span._record_exception,
26
- set_status_on_exception=span._set_status_on_exception,
27
- limits=span._limits,
28
- instrumentation_scope=span.instrumentation_scope,
29
- )
30
-
31
- self._span = span
32
-
33
- ## --- PROXY METHODS --- ##
34
-
35
- def get_span_context(self):
36
- return self._span.get_span_context()
37
-
38
- def is_recording(self) -> bool:
39
- return self._span.is_recording()
40
-
41
- def update_name(self, name: str) -> None:
42
- self._span.update_name(name)
43
-
44
- def set_status(
45
- self,
46
- status: Union[Status, StatusCode],
47
- description: Optional[str] = None,
48
- ) -> None:
49
- self._span.set_status(status=status, description=description)
50
-
51
- def end(self) -> None:
52
- self._span.end()
53
-
54
- ## --- CUSTOM METHODS W/ ATTRIBUTES SERALIZATION --- ##
55
-
56
- def set_attributes(
57
- self,
58
- attributes: Dict[str, Any],
59
- namespace: Optional[str] = None,
60
- max_depth: Optional[int] = None,
61
- ) -> None:
62
- self._span.set_attributes(
63
- attributes=serialize(
64
- namespace=namespace,
65
- attributes=attributes,
66
- max_depth=max_depth,
67
- )
68
- )
69
-
70
- def set_attribute(
71
- self,
72
- key: str,
73
- value: Any,
74
- namespace: Optional[str] = None,
75
- ) -> None:
76
- self.set_attributes({key: value}, namespace)
77
-
78
- def add_event(
79
- self,
80
- name: str,
81
- attributes: Optional[Dict[str, Any]] = None,
82
- timestamp: Optional[int] = None,
83
- namespace: Optional[str] = None,
84
- ) -> None:
85
- self._span.add_event(
86
- name=name,
87
- attributes=serialize(
88
- namespace=namespace,
89
- attributes=attributes,
90
- ),
91
- timestamp=timestamp,
92
- )
93
-
94
- def add_link(
95
- self,
96
- context: SpanContext,
97
- attributes: Optional[Dict[str, Any]] = None,
98
- namespace: Optional[str] = None,
99
- ) -> None:
100
- self._span.add_link(
101
- context=context,
102
- attributes=serialize(
103
- namespace=namespace,
104
- attributes=attributes,
105
- ),
106
- )
107
-
108
- def record_exception(
109
- self,
110
- exception: BaseException,
111
- attributes: Optional[Dict[str, Any]] = None,
112
- timestamp: Optional[int] = None,
113
- escaped: bool = False,
114
- namespace: Optional[str] = None,
115
- ) -> None:
116
- self._span.record_exception(
117
- exception=exception,
118
- attributes=serialize(
119
- namespace=namespace,
120
- attributes=attributes,
121
- ),
122
- timestamp=timestamp,
123
- escaped=escaped,
124
- )
@@ -1,174 +0,0 @@
1
- from typing import Optional, Any, Dict
2
-
3
- from httpx import get as check
4
-
5
- from opentelemetry.trace import (
6
- get_current_span,
7
- set_tracer_provider,
8
- get_tracer_provider,
9
- Status,
10
- StatusCode,
11
- )
12
- from opentelemetry.sdk.trace import Span, Tracer, TracerProvider
13
- from opentelemetry.sdk.resources import Resource
14
-
15
- from agenta.sdk.utils.singleton import Singleton
16
- from agenta.sdk.utils.exceptions import suppress # USE IT !
17
- from agenta.sdk.utils.logging import log
18
-
19
- from agenta.sdk.tracing.processors import TraceProcessor
20
- from agenta.sdk.tracing.exporters import ConsoleExporter, InlineExporter, OTLPExporter
21
- from agenta.sdk.tracing.spans import CustomSpan
22
- from agenta.sdk.tracing.context import tracing_context
23
- from agenta.sdk.tracing.inline import parse_inline_trace
24
-
25
-
26
- class Tracing(metaclass=Singleton):
27
- VERSION = "0.1.0"
28
-
29
- Status = Status
30
- StatusCode = StatusCode
31
-
32
- def __init__(
33
- self,
34
- url: str,
35
- ) -> None:
36
- # ENDPOINT (OTLP)
37
- self.otlp_url = url
38
- # AUTHENTICATION (OTLP)
39
- self.project_id: Optional[str] = None
40
- # AUTHORIZATION (OTLP)
41
- self.api_key: Optional[str] = None
42
- # HEADERS (OTLP)
43
- self.headers: Dict[str, str] = dict()
44
- # REFERENCES
45
- self.references: Dict[str, str] = dict()
46
-
47
- # TRACER PROVIDER
48
- self.tracer_provider: Optional[TracerProvider] = None
49
- # TRACER
50
- self.tracer: Optional[Tracer] = None
51
- # INLINE SPANS for INLINE TRACES (INLINE PROCESSOR)
52
- self.inline_spans: Dict[str, Any] = dict()
53
-
54
- # PUBLIC
55
-
56
- def configure(
57
- self,
58
- project_id: Optional[str] = None,
59
- api_key: Optional[str] = None,
60
- #
61
- app_id: Optional[str] = None,
62
- ):
63
- # AUTHENTICATION (OTLP)
64
- self.project_id = project_id # "f7943e42-ec69-498e-bf58-8db034b9286e"
65
- self.app_id = app_id
66
- # AUTHORIZATION (OTLP)
67
- self.api_key = api_key
68
- # HEADERS (OTLP)
69
- self.headers = {}
70
- if project_id:
71
- self.headers.update(**{"AG-PROJECT-ID": project_id})
72
- if app_id:
73
- self.headers.update(**{"AG-APP-ID": app_id})
74
- if api_key:
75
- self.headers.update(**{"Authorization": self.api_key})
76
- # REFERENCES
77
- self.references = {"application_id": app_id}
78
-
79
- # TRACER PROVIDER
80
- self.tracer_provider = TracerProvider(
81
- resource=Resource(attributes={"service.name": "agenta-sdk"})
82
- )
83
- # TRACE PROCESSORS -- CONSOLE
84
- # _console = TraceProcessor(
85
- # ConsoleExporter(),
86
- # references=self.references,
87
- # )
88
- # self.tracer_provider.add_span_processor(_console)
89
- # TRACE PROCESSORS -- INLINE
90
- self.inline = TraceProcessor(
91
- InlineExporter(registry=self.inline_spans),
92
- references=self.references,
93
- )
94
- self.tracer_provider.add_span_processor(self.inline)
95
- # TRACE PROCESSORS -- OTLP
96
- try:
97
- log.info(f"Connecting to the remote trace receiver at {self.otlp_url}...")
98
-
99
- check(self.otlp_url, headers=self.headers, timeout=1)
100
-
101
- log.info(f"Connection established.")
102
-
103
- _otlp = TraceProcessor(
104
- OTLPExporter(endpoint=self.otlp_url, headers=self.headers),
105
- references=self.references,
106
- )
107
-
108
- self.tracer_provider.add_span_processor(_otlp)
109
- except Exception as e:
110
- log.error(e)
111
- log.warning(f"Connection failed.")
112
- log.warning(
113
- f"Warning: Your traces will not be exported since {self.otlp_url} is unreachable."
114
- )
115
- # GLOBAL TRACER PROVIDER -- INSTRUMENTATION LIBRARIES
116
- set_tracer_provider(self.tracer_provider)
117
- # TRACER
118
- self.tracer: Tracer = self.tracer_provider.get_tracer("agenta.tracer")
119
-
120
- def get_current_span(
121
- self,
122
- ):
123
- _span = get_current_span()
124
-
125
- if _span.is_recording():
126
- return CustomSpan(_span)
127
-
128
- return _span
129
-
130
- def store_internals(
131
- self,
132
- attributes: Dict[str, Any],
133
- span: Optional[Span] = None,
134
- ):
135
- if span is None:
136
- span = self.get_current_span()
137
-
138
- span.set_attributes(attributes={"internals": attributes}, namespace="data")
139
-
140
- def is_inline_trace_ready(
141
- self,
142
- trace_id: int,
143
- ) -> bool:
144
- is_ready = self.inline.is_ready(trace_id)
145
-
146
- return is_ready
147
-
148
- def get_inline_trace(
149
- self,
150
- trace_id: int,
151
- ) -> Dict[str, Any]:
152
- if trace_id is None:
153
- return {}
154
-
155
- is_ready = self.inline.is_ready(trace_id)
156
-
157
- if is_ready is False:
158
- return {}
159
-
160
- otel_spans = self.inline.fetch(trace_id)
161
-
162
- if not otel_spans:
163
- return {}
164
-
165
- inline_trace = parse_inline_trace(self.project_id or self.app_id, otel_spans)
166
-
167
- return inline_trace
168
-
169
-
170
- def get_tracer(tracing: Tracing) -> Tracer:
171
- if tracing is None or tracing.tracer is None or tracing.tracer_provider is None:
172
- return get_tracer_provider().get_tracer("default.tracer")
173
-
174
- return tracing.tracer
@@ -1,19 +0,0 @@
1
- from contextlib import AbstractContextManager
2
- from traceback import format_exc
3
- from agenta.sdk.utils.logging import log
4
-
5
-
6
- class suppress(AbstractContextManager):
7
- def __init__(self):
8
- pass
9
-
10
- def __enter__(self):
11
- pass
12
-
13
- def __exit__(self, exc_type, exc_value, exc_tb):
14
- if exc_type is None:
15
- return
16
- else:
17
- print("Agenta SDK - Tracing Exception")
18
- log.error(f"{exc_type.__name__}: {exc_value}\n{format_exc()}")
19
- return
@@ -1,13 +0,0 @@
1
- from threading import Lock
2
-
3
-
4
- class Singleton(type):
5
- _instances = {}
6
-
7
- _lock: Lock = Lock()
8
-
9
- def __call__(cls, *args, **kwargs):
10
- with cls._lock:
11
- if cls not in cls._instances:
12
- cls._instances[cls] = super().__call__(*args, **kwargs)
13
- return cls._instances[cls]