agenta 0.25.3a1__py3-none-any.whl → 0.25.4__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 +2 -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} +125 -136
  11. agenta/sdk/decorators/tracing.py +81 -243
  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.3a1.dist-info → agenta-0.25.4.dist-info}/METADATA +2 -4
  24. {agenta-0.25.3a1.dist-info → agenta-0.25.4.dist-info}/RECORD +26 -36
  25. {agenta-0.25.3a1.dist-info → agenta-0.25.4.dist-info}/WHEEL +1 -1
  26. agenta/sdk/context/__init__.py +0 -0
  27. agenta/sdk/context/routing.py +0 -25
  28. agenta/sdk/context/tracing.py +0 -3
  29. agenta/sdk/decorators/__init__.py +0 -0
  30. agenta/sdk/litellm/__init__.py +0 -1
  31. agenta/sdk/litellm/litellm.py +0 -275
  32. agenta/sdk/tracing/attributes.py +0 -181
  33. agenta/sdk/tracing/context.py +0 -21
  34. agenta/sdk/tracing/conventions.py +0 -43
  35. agenta/sdk/tracing/exporters.py +0 -53
  36. agenta/sdk/tracing/inline.py +0 -1230
  37. agenta/sdk/tracing/processors.py +0 -65
  38. agenta/sdk/tracing/spans.py +0 -124
  39. agenta/sdk/tracing/tracing.py +0 -171
  40. agenta/sdk/utils/exceptions.py +0 -18
  41. agenta/sdk/utils/singleton.py +0 -13
  42. {agenta-0.25.3a1.dist-info → agenta-0.25.4.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,171 +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
- self.otlp_url = "http://127.0.0.1:8000/api/observability/v1/otlp/traces"
39
- # AUTHENTICATION (OTLP)
40
- self.project_id: Optional[str] = None
41
- # AUTHORIZATION (OTLP)
42
- self.api_key: Optional[str] = None
43
- # HEADERS (OTLP)
44
- self.headers: Dict[str, str] = dict()
45
- # REFERENCES
46
- self.references: Dict[str, str] = dict()
47
-
48
- # TRACER PROVIDER
49
- self.tracer_provider: Optional[TracerProvider] = None
50
- # TRACER
51
- self.tracer: Optional[Tracer] = None
52
- # INLINE SPANS for INLINE TRACES (INLINE PROCESSOR)
53
- self.inline_spans: Dict[str, Any] = dict()
54
-
55
- # PUBLIC
56
-
57
- def configure(
58
- self,
59
- project_id: Optional[str] = None,
60
- api_key: Optional[str] = None,
61
- #
62
- app_id: Optional[str] = None,
63
- ):
64
- # AUTHENTICATION (OTLP)
65
- # self.project_id = project_id
66
- self.project_id = "f7943e42-ec69-498e-bf58-8db034b9286e"
67
- # AUTHORIZATION (OTLP)
68
- self.api_key = api_key
69
- # HEADERS (OTLP)
70
- self.headers = {"AG-PROJECT-ID": self.project_id}
71
- if api_key:
72
- # self.headers.update(**{"Authorization": f"Api-Key {self.api_key}"})
73
- self.headers.update(**{"Authorization": self.api_key})
74
- # REFERENCES
75
- self.references = {"application.id": app_id}
76
-
77
- # TRACER PROVIDER
78
- self.tracer_provider = TracerProvider(
79
- resource=Resource(attributes={"service.name": "agenta-sdk"})
80
- )
81
- # TRACE PROCESSORS -- CONSOLE
82
- # _console = TraceProcessor(
83
- # ConsoleExporter(),
84
- # references=self.references,
85
- # )
86
- # self.tracer_provider.add_span_processor(_console)
87
- # TRACE PROCESSORS -- INLINE
88
- self.inline = TraceProcessor(
89
- InlineExporter(registry=self.inline_spans),
90
- references=self.references,
91
- )
92
- self.tracer_provider.add_span_processor(self.inline)
93
- # TRACE PROCESSORS -- OTLP
94
- try:
95
- log.info(f"Connecting to the remote trace receiver at {self.otlp_url}...")
96
-
97
- check(self.otlp_url, headers=self.headers)
98
-
99
- log.info(f"Connection established.")
100
-
101
- _otlp = TraceProcessor(
102
- OTLPExporter(endpoint=self.otlp_url, headers=self.headers),
103
- references=self.references,
104
- )
105
-
106
- self.tracer_provider.add_span_processor(_otlp)
107
- except:
108
- log.warning(f"Connection failed.")
109
- log.warning(
110
- f"Warning: Your traces will not be exported since {self.otlp_url} is unreachable."
111
- )
112
- # GLOBAL TRACER PROVIDER -- INSTRUMENTATION LIBRARIES
113
- set_tracer_provider(self.tracer_provider)
114
- # TRACER
115
- self.tracer: Tracer = self.tracer_provider.get_tracer("agenta.tracer")
116
-
117
- def get_current_span(
118
- self,
119
- ):
120
- _span = get_current_span()
121
-
122
- if _span.is_recording():
123
- return CustomSpan(_span)
124
-
125
- return _span
126
-
127
- def store_internals(
128
- self,
129
- attributes: Dict[str, Any],
130
- span: Optional[Span] = None,
131
- ):
132
- if span is None:
133
- span = self.get_current_span()
134
-
135
- span.set_attributes(attributes={"internals": attributes}, namespace="data")
136
-
137
- def is_inline_trace_ready(
138
- self,
139
- trace_id: int,
140
- ) -> bool:
141
- is_ready = self.inline.is_ready(trace_id)
142
-
143
- return is_ready
144
-
145
- def get_inline_trace(
146
- self,
147
- trace_id: int,
148
- ) -> Dict[str, Any]:
149
- if trace_id is None:
150
- return {}
151
-
152
- is_ready = self.inline.is_ready(trace_id)
153
-
154
- if is_ready is False:
155
- return {}
156
-
157
- otel_spans = self.inline.fetch(trace_id)
158
-
159
- if not otel_spans:
160
- return {}
161
-
162
- inline_trace = parse_inline_trace(self.project_id, otel_spans)
163
-
164
- return inline_trace
165
-
166
-
167
- def get_tracer(tracing: Tracing) -> Tracer:
168
- if tracing is None or tracing.tracer is None or tracing.tracer_provider is None:
169
- return get_tracer_provider().get_tracer("default.tracer")
170
-
171
- return tracing.tracer
@@ -1,18 +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
- log.error(f"{exc_type.__name__}: {exc_value}\n{format_exc()}")
18
- 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]