agenta 0.26.0a0__py3-none-any.whl → 0.27.0a0__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 +6 -7
- agenta/client/backend/client.py +22 -14
- agenta/client/backend/core/http_client.py +23 -15
- agenta/sdk/__init__.py +27 -6
- agenta/sdk/agenta_init.py +73 -26
- agenta/sdk/config_manager.py +2 -2
- agenta/sdk/context/__init__.py +0 -0
- agenta/sdk/context/routing.py +25 -0
- agenta/sdk/context/tracing.py +3 -0
- agenta/sdk/decorators/__init__.py +0 -0
- agenta/sdk/decorators/{llm_entrypoint.py → routing.py} +137 -124
- agenta/sdk/decorators/tracing.py +228 -76
- agenta/sdk/litellm/__init__.py +1 -0
- agenta/sdk/litellm/litellm.py +277 -0
- agenta/sdk/router.py +0 -7
- agenta/sdk/tracing/__init__.py +1 -0
- agenta/sdk/tracing/attributes.py +181 -0
- agenta/sdk/tracing/context.py +21 -0
- agenta/sdk/tracing/conventions.py +43 -0
- agenta/sdk/tracing/exporters.py +53 -0
- agenta/sdk/tracing/inline.py +1306 -0
- agenta/sdk/tracing/processors.py +65 -0
- agenta/sdk/tracing/spans.py +124 -0
- agenta/sdk/tracing/tracing.py +174 -0
- agenta/sdk/types.py +0 -12
- agenta/sdk/utils/{helper/openai_cost.py → costs.py} +3 -0
- agenta/sdk/utils/debug.py +5 -5
- agenta/sdk/utils/exceptions.py +19 -0
- agenta/sdk/utils/globals.py +3 -5
- agenta/sdk/{tracing/logger.py → utils/logging.py} +3 -5
- agenta/sdk/utils/singleton.py +13 -0
- {agenta-0.26.0a0.dist-info → agenta-0.27.0a0.dist-info}/METADATA +5 -1
- {agenta-0.26.0a0.dist-info → agenta-0.27.0a0.dist-info}/RECORD +35 -25
- agenta/sdk/context.py +0 -41
- agenta/sdk/decorators/base.py +0 -10
- agenta/sdk/tracing/callbacks.py +0 -187
- agenta/sdk/tracing/llm_tracing.py +0 -617
- agenta/sdk/tracing/tasks_manager.py +0 -129
- agenta/sdk/tracing/tracing_context.py +0 -27
- {agenta-0.26.0a0.dist-info → agenta-0.27.0a0.dist-info}/WHEEL +0 -0
- {agenta-0.26.0a0.dist-info → agenta-0.27.0a0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
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
|
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
)
|
|
@@ -0,0 +1,174 @@
|
|
|
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
|
agenta/sdk/types.py
CHANGED
|
@@ -186,15 +186,3 @@ class FileInputURL(HttpUrl):
|
|
|
186
186
|
@classmethod
|
|
187
187
|
def __schema_type_properties__(cls) -> dict:
|
|
188
188
|
return {"x-parameter": "file_url", "type": "string"}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
class Context(BaseModel):
|
|
192
|
-
model_config = ConfigDict(extra="allow")
|
|
193
|
-
|
|
194
|
-
def to_json(self):
|
|
195
|
-
return self.model_dump()
|
|
196
|
-
|
|
197
|
-
@classmethod
|
|
198
|
-
def from_json(cls, json_str: str):
|
|
199
|
-
data = json.loads(json_str)
|
|
200
|
-
return cls(**data)
|
|
@@ -49,6 +49,9 @@ MODEL_COST_PER_1K_TOKENS = {
|
|
|
49
49
|
"gpt-35-turbo-16k-completion": 0.004,
|
|
50
50
|
"gpt-35-turbo-16k-0613-completion": 0.004,
|
|
51
51
|
# Others
|
|
52
|
+
"text-embedding-ada-002": 0.1,
|
|
53
|
+
"text-ada-002": 0.1,
|
|
54
|
+
"adav2": 0.1,
|
|
52
55
|
"text-ada-001": 0.0004,
|
|
53
56
|
"ada": 0.0004,
|
|
54
57
|
"text-babbage-001": 0.0005,
|
agenta/sdk/utils/debug.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from inspect import iscoroutinefunction
|
|
2
2
|
from functools import wraps
|
|
3
3
|
|
|
4
|
-
from agenta.sdk.
|
|
4
|
+
from agenta.sdk.utils.logging import log
|
|
5
5
|
|
|
6
6
|
DEBUG = False
|
|
7
7
|
SHIFT = 7
|
|
@@ -14,7 +14,7 @@ def debug(shift=1, req=False, res=False, chars=[">", "<"]):
|
|
|
14
14
|
@wraps(f)
|
|
15
15
|
async def async_log_wrapper(*args, **kwargs):
|
|
16
16
|
if DEBUG:
|
|
17
|
-
|
|
17
|
+
log.debug(
|
|
18
18
|
" ".join(
|
|
19
19
|
[
|
|
20
20
|
chars[0] * shift + " " * (SHIFT - shift),
|
|
@@ -26,7 +26,7 @@ def debug(shift=1, req=False, res=False, chars=[">", "<"]):
|
|
|
26
26
|
)
|
|
27
27
|
result = await f(*args, **kwargs)
|
|
28
28
|
if DEBUG:
|
|
29
|
-
|
|
29
|
+
log.debug(
|
|
30
30
|
" ".join(
|
|
31
31
|
[
|
|
32
32
|
chars[1] * shift + " " * (SHIFT - shift),
|
|
@@ -40,7 +40,7 @@ def debug(shift=1, req=False, res=False, chars=[">", "<"]):
|
|
|
40
40
|
@wraps(f)
|
|
41
41
|
def log_wrapper(*args, **kwargs):
|
|
42
42
|
if DEBUG:
|
|
43
|
-
|
|
43
|
+
log.debug(
|
|
44
44
|
" ".join(
|
|
45
45
|
[
|
|
46
46
|
chars[0] * shift + " " * (SHIFT - shift),
|
|
@@ -52,7 +52,7 @@ def debug(shift=1, req=False, res=False, chars=[">", "<"]):
|
|
|
52
52
|
)
|
|
53
53
|
result = f(*args, **kwargs)
|
|
54
54
|
if DEBUG:
|
|
55
|
-
|
|
55
|
+
log.debug(
|
|
56
56
|
" ".join(
|
|
57
57
|
[
|
|
58
58
|
chars[1] * shift + " " * (SHIFT - shift),
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
agenta/sdk/utils/globals.py
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import agenta
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
def set_global(
|
|
5
|
-
"""Allows usage of agenta.config and agenta.
|
|
4
|
+
def set_global(config=None, tracing=None):
|
|
5
|
+
"""Allows usage of agenta.config and agenta.tracing in the user's code.
|
|
6
6
|
|
|
7
7
|
Args:
|
|
8
|
-
setup: _description_. Defaults to None.
|
|
9
8
|
config: _description_. Defaults to None.
|
|
9
|
+
tracing: _description_. Defaults to None.
|
|
10
10
|
"""
|
|
11
|
-
if setup is not None:
|
|
12
|
-
agenta.setup = setup
|
|
13
11
|
if config is not None:
|
|
14
12
|
agenta.config = config
|
|
15
13
|
if tracing is not None:
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
class
|
|
5
|
-
def __init__(self, name="
|
|
4
|
+
class Logger:
|
|
5
|
+
def __init__(self, name="agenta.logger", level=logging.DEBUG):
|
|
6
6
|
self.logger = logging.getLogger(name)
|
|
7
7
|
self.logger.setLevel(level)
|
|
8
8
|
|
|
9
|
-
# Add a stream logger to view the logs in the console
|
|
10
9
|
console_handler = logging.StreamHandler()
|
|
11
10
|
self.logger.addHandler(console_handler)
|
|
12
11
|
|
|
@@ -15,5 +14,4 @@ class LLMLogger:
|
|
|
15
14
|
return self.logger
|
|
16
15
|
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
llm_logger = LLMLogger().log
|
|
17
|
+
log = Logger().log
|
|
@@ -0,0 +1,13 @@
|
|
|
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]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: agenta
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.0a0
|
|
4
4
|
Summary: The SDK for agenta is an open-source LLMOps platform.
|
|
5
5
|
Home-page: https://agenta.ai
|
|
6
6
|
Keywords: LLMOps,LLM,evaluation,prompt engineering
|
|
@@ -23,6 +23,10 @@ Requires-Dist: fastapi (>=0.100.0)
|
|
|
23
23
|
Requires-Dist: httpx (>=0.24,<0.28)
|
|
24
24
|
Requires-Dist: importlib-metadata (>=8.0.0,<9.0)
|
|
25
25
|
Requires-Dist: ipdb (>=0.13)
|
|
26
|
+
Requires-Dist: litellm (>=1.48.0,<2.0.0)
|
|
27
|
+
Requires-Dist: opentelemetry-api (>=1.27.0,<2.0.0)
|
|
28
|
+
Requires-Dist: opentelemetry-exporter-otlp (>=1.27.0,<2.0.0)
|
|
29
|
+
Requires-Dist: opentelemetry-sdk (>=1.27.0,<2.0.0)
|
|
26
30
|
Requires-Dist: posthog (>=3.1.0,<4.0.0)
|
|
27
31
|
Requires-Dist: pydantic (>=2)
|
|
28
32
|
Requires-Dist: pymongo (>=4.6.3,<5.0.0)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
agenta/__init__.py,sha256=
|
|
1
|
+
agenta/__init__.py,sha256=cd3c7bpyfZC8ho2Dc299bg8l_BDRQ3TFbd9Tnn2UQTY,923
|
|
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
|
|
@@ -14,7 +14,7 @@ agenta/client/backend/apps/__init__.py,sha256=9mUnTDeA1TxYvkj1l01A1prqsJV0ERRY2t
|
|
|
14
14
|
agenta/client/backend/apps/client.py,sha256=9rWax7LlEIpXdqq4McPAkvwHweSTomnyrFxFo8ehYy0,54136
|
|
15
15
|
agenta/client/backend/bases/__init__.py,sha256=9mUnTDeA1TxYvkj1l01A1prqsJV0ERRY2tzkY1fA4MQ,64
|
|
16
16
|
agenta/client/backend/bases/client.py,sha256=BZsz5eXaa2voZdJXqgd5J5hPUuYvWwIcPCWyl49w-oY,6028
|
|
17
|
-
agenta/client/backend/client.py,sha256=
|
|
17
|
+
agenta/client/backend/client.py,sha256=k262wVUWPYWbZhLiZec7sTLfh8CD7tfCYdFKyLqUMi0,102659
|
|
18
18
|
agenta/client/backend/configs/__init__.py,sha256=9mUnTDeA1TxYvkj1l01A1prqsJV0ERRY2tzkY1fA4MQ,64
|
|
19
19
|
agenta/client/backend/configs/client.py,sha256=qtrRdRuNIZBjh9Ykj7eNKhocp7dFdFQoDSbUduVjKJ0,19089
|
|
20
20
|
agenta/client/backend/containers/__init__.py,sha256=Haw2PwiPhNvM26PLQN57jY0bN-QqPoDG4VA-P_uGL3A,153
|
|
@@ -26,7 +26,7 @@ agenta/client/backend/core/api_error.py,sha256=TtMtCdxXjd7Tasc9c8ooFg124nPrb2MXG
|
|
|
26
26
|
agenta/client/backend/core/client_wrapper.py,sha256=mU22mZBjz2QXalKJLDGo1qNeAt1awLxRMO8fzbPbnr8,1829
|
|
27
27
|
agenta/client/backend/core/datetime_utils.py,sha256=BHjt_H3WVslcuPsr6qjJoVif_SsdLvFN0c43ABE5UiQ,1069
|
|
28
28
|
agenta/client/backend/core/file.py,sha256=vliNmlB7PbDfi4EKiVPNq5QaGXJ4zlDBGupv7Qciy7g,1520
|
|
29
|
-
agenta/client/backend/core/http_client.py,sha256=
|
|
29
|
+
agenta/client/backend/core/http_client.py,sha256=1ORQxbKS0c6nMbeiANucMrlwUImmLXlCfjBbR_W-LSY,20440
|
|
30
30
|
agenta/client/backend/core/jsonable_encoder.py,sha256=SHXw4G4n-f0IPgNkxj_-Fip3kN8NUAI-YrKxdZw8kl0,3662
|
|
31
31
|
agenta/client/backend/core/pydantic_utilities.py,sha256=sLzQZQLS_y66SZSBMtJE7YrQK8INda-ta1tKwAHabGk,7540
|
|
32
32
|
agenta/client/backend/core/query_encoder.py,sha256=8qYl5VPl1jU4cDF0X7oSU_DXjlVWY5ayigFBpNTMGOA,2150
|
|
@@ -132,28 +132,38 @@ 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=k6lzJF6gzaFdzq_FJ3chBu6ug8pNCT3_-bfeB1ZqGkg,1165
|
|
136
|
+
agenta/sdk/agenta_init.py,sha256=Wg9LOD8pQiz4F6-QepnqWmwdBKe_FJK-AHs6_HvO1x4,10603
|
|
137
137
|
agenta/sdk/assets.py,sha256=Zv4i8MVUSB3jMODQon1mzJtYxuntmrCNjLGk8f-2fls,2856
|
|
138
138
|
agenta/sdk/client.py,sha256=trKyBOYFZRk0v5Eptxvh87yPf50Y9CqY6Qgv4Fy-VH4,2142
|
|
139
|
-
agenta/sdk/config_manager.py,sha256=
|
|
140
|
-
agenta/sdk/context.py,sha256=
|
|
141
|
-
agenta/sdk/
|
|
142
|
-
agenta/sdk/
|
|
143
|
-
agenta/sdk/decorators/
|
|
144
|
-
agenta/sdk/
|
|
145
|
-
agenta/sdk/tracing
|
|
146
|
-
agenta/sdk/
|
|
147
|
-
agenta/sdk/
|
|
148
|
-
agenta/sdk/
|
|
149
|
-
agenta/sdk/tracing/
|
|
150
|
-
agenta/sdk/tracing/
|
|
151
|
-
agenta/sdk/
|
|
139
|
+
agenta/sdk/config_manager.py,sha256=HFOJpJKBkhlA0C-KPuxb4-bHNZeZqdpmx_beoX4lQw8,7997
|
|
140
|
+
agenta/sdk/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
141
|
+
agenta/sdk/context/routing.py,sha256=gOoOM88hSjIjzQ3ni68TjUoq7WtwSH3kB07YjCYvW2c,631
|
|
142
|
+
agenta/sdk/context/tracing.py,sha256=UmmW15UFFsvxS0myS6aD9wBk5iNepNlQi4tEQ_ejfYM,96
|
|
143
|
+
agenta/sdk/decorators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
144
|
+
agenta/sdk/decorators/routing.py,sha256=4vJsFwyXUx1cuzILVOzELDfv17QnYTXpIE2NwFnC__I,35427
|
|
145
|
+
agenta/sdk/decorators/tracing.py,sha256=hGh8xnoiQBC-ycWOTHm-a6bX60c1aEkN3NGV9JZ0F2w,11202
|
|
146
|
+
agenta/sdk/litellm/__init__.py,sha256=Bpz1gfHQc0MN1yolWcjifLWznv6GjHggvRGQSpxpihM,37
|
|
147
|
+
agenta/sdk/litellm/litellm.py,sha256=j4WyRTQdxLkvelaPm5BfUbaUxkbQXDhyr3yp9yXo1RQ,8289
|
|
148
|
+
agenta/sdk/router.py,sha256=mOguvtOwl2wmyAgOuWTsf98pQwpNiUILKIo67W_hR3A,119
|
|
149
|
+
agenta/sdk/tracing/__init__.py,sha256=rQNe5-zT5Kt7_CDhq-lnUIi1EYTBVzVf_MbfcIxVD98,41
|
|
150
|
+
agenta/sdk/tracing/attributes.py,sha256=0Ld0A4eL6EAWwbhBY0Qp7MLWXXbBsd8EDtbBuwIy1PI,4775
|
|
151
|
+
agenta/sdk/tracing/context.py,sha256=KDQYjRcmbpb6e0xEuX-bAQGhEjwx4H2nwybRPOKCDjo,578
|
|
152
|
+
agenta/sdk/tracing/conventions.py,sha256=YFkKPls77sl5YOXrRjfn4erEjczMXThc7b-rRaVVTuo,722
|
|
153
|
+
agenta/sdk/tracing/exporters.py,sha256=e-SfpN8dKQ0vuBZQTZ6qgIMBhyriOrVeLYJkv-us0Zs,1328
|
|
154
|
+
agenta/sdk/tracing/inline.py,sha256=n9_XM6VJzg9v_z7xjFHyK6aKABn_YpEINXyvXSyOgcw,35821
|
|
155
|
+
agenta/sdk/tracing/processors.py,sha256=PRQpj8aOmOjvf71M48AtCurIxVFg2ZZWRtJLtlB4xyE,1974
|
|
156
|
+
agenta/sdk/tracing/spans.py,sha256=AnQuuyuCGST6n_He4SF5WdrtMts9JlE8v6rVRdm2rRg,3570
|
|
157
|
+
agenta/sdk/tracing/tracing.py,sha256=5r0whzLzF2bwYKZkUN3QDjq8AketEb-9sM4nqnO9zzM,5168
|
|
158
|
+
agenta/sdk/types.py,sha256=B7C7Jpeq0CpmLwmN1dmpggJsZX8WpxyyM42PkdSsx3s,5669
|
|
152
159
|
agenta/sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
153
|
-
agenta/sdk/utils/
|
|
154
|
-
agenta/sdk/utils/
|
|
155
|
-
agenta/sdk/utils/
|
|
160
|
+
agenta/sdk/utils/costs.py,sha256=i8C7ud__pThLS55XkN4YW8czXtGeXr2mx7jjcOFeiXg,5955
|
|
161
|
+
agenta/sdk/utils/debug.py,sha256=DxiCAeXxxrcEZT2CjlNA6BMvujGP4nzQ-rfb-_mLMck,2114
|
|
162
|
+
agenta/sdk/utils/exceptions.py,sha256=kzU5bNBMZvVv0xnwvc5osVMsb_Ujm0qqeem9wpNo2z0,500
|
|
163
|
+
agenta/sdk/utils/globals.py,sha256=2HhyzWn55BbYNCZ3rT8dAxk1GGXuGQPbtq_THjaHbBw,372
|
|
164
|
+
agenta/sdk/utils/logging.py,sha256=FKzAO5eHjR_qvpEnc4tKXUA6WftmwdwYwuJK6CbSc84,379
|
|
156
165
|
agenta/sdk/utils/preinit.py,sha256=YlJL7RLfel0R7DFp-jK7OV-z4ZIQJM0oupYlk7g8b5o,1278
|
|
166
|
+
agenta/sdk/utils/singleton.py,sha256=17Ph7LGnnV8HkPjImruKita2ni03Ari5jr0jqm__4sc,312
|
|
157
167
|
agenta/templates/compose_email/README.md,sha256=ss7vZPpI1Hg0VmYtFliwq_r5LnqbCy_S5OQDXg8UoIA,308
|
|
158
168
|
agenta/templates/compose_email/app.py,sha256=SG8QnBkC49MtvWa2z5_YQ2d8wxZxhO_hWs15j3CsWvc,2384
|
|
159
169
|
agenta/templates/compose_email/env.example,sha256=g9AE5bYcGPpxawXMJ96gh8oenEPCHTabsiOnfQo3c5k,70
|
|
@@ -169,7 +179,7 @@ agenta/templates/simple_prompt/app.py,sha256=kODgF6lhzsaJPdgL5b21bUki6jkvqjWZzWR
|
|
|
169
179
|
agenta/templates/simple_prompt/env.example,sha256=g9AE5bYcGPpxawXMJ96gh8oenEPCHTabsiOnfQo3c5k,70
|
|
170
180
|
agenta/templates/simple_prompt/requirements.txt,sha256=ywRglRy7pPkw8bljmMEJJ4aOOQKrt9FGKULZ-DGkoBU,23
|
|
171
181
|
agenta/templates/simple_prompt/template.toml,sha256=DQBtRrF4GU8LBEXOZ-GGuINXMQDKGTEG5y37tnvIUIE,60
|
|
172
|
-
agenta-0.
|
|
173
|
-
agenta-0.
|
|
174
|
-
agenta-0.
|
|
175
|
-
agenta-0.
|
|
182
|
+
agenta-0.27.0a0.dist-info/METADATA,sha256=O3yhji_Fs-vomvmT-XV3jDff3pQYFgpkFt1zGT0X-Y4,31738
|
|
183
|
+
agenta-0.27.0a0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
184
|
+
agenta-0.27.0a0.dist-info/entry_points.txt,sha256=PDiu8_8AsL7ibU9v4iNoOKR1S7F2rdxjlEprjM9QOgo,46
|
|
185
|
+
agenta-0.27.0a0.dist-info/RECORD,,
|
agenta/sdk/context.py
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import sqlite3
|
|
3
|
-
from typing import List
|
|
4
|
-
from .types import Context
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def setup_db():
|
|
8
|
-
conn = sqlite3.connect("context.db")
|
|
9
|
-
c = conn.cursor()
|
|
10
|
-
c.execute(
|
|
11
|
-
"""
|
|
12
|
-
CREATE TABLE IF NOT EXISTS contexts
|
|
13
|
-
(id INTEGER PRIMARY KEY AUTOINCREMENT, context TEXT)
|
|
14
|
-
"""
|
|
15
|
-
)
|
|
16
|
-
conn.commit()
|
|
17
|
-
conn.close()
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def get_contexts() -> List[Context]:
|
|
21
|
-
contexts = []
|
|
22
|
-
conn = sqlite3.connect("context.db")
|
|
23
|
-
c = conn.cursor()
|
|
24
|
-
for row in c.execute("SELECT * FROM contexts"):
|
|
25
|
-
context_data = json.loads(row[1])
|
|
26
|
-
contexts.append(Context.parse_obj(context_data))
|
|
27
|
-
conn.close()
|
|
28
|
-
return contexts
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def save_context(result: Context):
|
|
32
|
-
conn = sqlite3.connect("context.db")
|
|
33
|
-
c = conn.cursor()
|
|
34
|
-
c.execute(
|
|
35
|
-
"""
|
|
36
|
-
INSERT INTO contexts (context) VALUES (?)
|
|
37
|
-
""",
|
|
38
|
-
(json.dumps(result.dict()),),
|
|
39
|
-
)
|
|
40
|
-
conn.commit()
|
|
41
|
-
conn.close()
|