agenta 0.25.4a2__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.
- agenta/__init__.py +7 -6
- agenta/client/backend/client.py +14 -22
- agenta/client/backend/core/http_client.py +15 -23
- agenta/client/backend/core/pydantic_utilities.py +0 -2
- agenta/sdk/__init__.py +6 -27
- agenta/sdk/agenta_init.py +26 -73
- agenta/sdk/config_manager.py +2 -2
- agenta/sdk/context.py +41 -0
- agenta/sdk/decorators/base.py +10 -0
- agenta/sdk/decorators/{routing.py → llm_entrypoint.py} +124 -137
- agenta/sdk/decorators/tracing.py +79 -247
- agenta/sdk/router.py +7 -0
- agenta/sdk/tracing/__init__.py +0 -1
- agenta/sdk/tracing/callbacks.py +187 -0
- agenta/sdk/tracing/llm_tracing.py +617 -0
- agenta/sdk/{utils/logging.py → tracing/logger.py} +5 -3
- agenta/sdk/tracing/tasks_manager.py +129 -0
- agenta/sdk/tracing/tracing_context.py +27 -0
- agenta/sdk/types.py +12 -0
- agenta/sdk/utils/debug.py +5 -5
- agenta/sdk/utils/globals.py +5 -3
- agenta/sdk/utils/{costs.py → helper/openai_cost.py} +0 -3
- {agenta-0.25.4a2.dist-info → agenta-0.25.4a4.dist-info}/METADATA +1 -5
- {agenta-0.25.4a2.dist-info → agenta-0.25.4a4.dist-info}/RECORD +26 -36
- agenta/sdk/context/__init__.py +0 -0
- agenta/sdk/context/routing.py +0 -25
- agenta/sdk/context/tracing.py +0 -3
- agenta/sdk/decorators/__init__.py +0 -0
- agenta/sdk/litellm/__init__.py +0 -1
- agenta/sdk/litellm/litellm.py +0 -277
- agenta/sdk/tracing/attributes.py +0 -181
- agenta/sdk/tracing/context.py +0 -21
- agenta/sdk/tracing/conventions.py +0 -43
- agenta/sdk/tracing/exporters.py +0 -53
- agenta/sdk/tracing/inline.py +0 -1307
- agenta/sdk/tracing/processors.py +0 -65
- agenta/sdk/tracing/spans.py +0 -124
- agenta/sdk/tracing/tracing.py +0 -174
- agenta/sdk/utils/exceptions.py +0 -19
- agenta/sdk/utils/singleton.py +0 -13
- {agenta-0.25.4a2.dist-info → agenta-0.25.4a4.dist-info}/WHEEL +0 -0
- {agenta-0.25.4a2.dist-info → agenta-0.25.4a4.dist-info}/entry_points.txt +0 -0
agenta/sdk/litellm/litellm.py
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import agenta as ag
|
|
2
|
-
|
|
3
|
-
from opentelemetry.trace import SpanKind
|
|
4
|
-
|
|
5
|
-
from agenta.sdk.tracing.spans import CustomSpan
|
|
6
|
-
from agenta.sdk.utils.exceptions import suppress
|
|
7
|
-
from agenta.sdk.utils.logging import log
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def litellm_handler():
|
|
11
|
-
try:
|
|
12
|
-
from litellm.utils import ModelResponse
|
|
13
|
-
from litellm.integrations.custom_logger import (
|
|
14
|
-
CustomLogger as LitellmCustomLogger,
|
|
15
|
-
)
|
|
16
|
-
except ImportError as exc:
|
|
17
|
-
raise ImportError(
|
|
18
|
-
"The litellm SDK is not installed. Please install it using `pip install litellm`."
|
|
19
|
-
) from exc
|
|
20
|
-
except Exception as exc:
|
|
21
|
-
raise Exception(
|
|
22
|
-
"Unexpected error occurred when importing litellm: {}".format(exc)
|
|
23
|
-
) from exc
|
|
24
|
-
|
|
25
|
-
class LitellmHandler(LitellmCustomLogger):
|
|
26
|
-
"""This handler is responsible for instrumenting certain events when using litellm to call LLMs.
|
|
27
|
-
|
|
28
|
-
Args:
|
|
29
|
-
LitellmCustomLogger (object): custom logger that allows us to override the events to capture.
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
def __init__(self):
|
|
33
|
-
self.span = None
|
|
34
|
-
|
|
35
|
-
def log_pre_api_call(
|
|
36
|
-
self,
|
|
37
|
-
model,
|
|
38
|
-
messages,
|
|
39
|
-
kwargs,
|
|
40
|
-
):
|
|
41
|
-
type = (
|
|
42
|
-
"chat"
|
|
43
|
-
if kwargs.get("call_type") in ["completion", "acompletion"]
|
|
44
|
-
else "embedding"
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
kind = SpanKind.CLIENT
|
|
48
|
-
|
|
49
|
-
self.span = CustomSpan(
|
|
50
|
-
ag.tracer.start_span(name=f"litellm_{kind.name.lower()}", kind=kind)
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
self.span.set_attributes(
|
|
54
|
-
attributes={"node": type},
|
|
55
|
-
namespace="type",
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
if not self.span:
|
|
59
|
-
log.error("LiteLLM callback error: span not found.")
|
|
60
|
-
return
|
|
61
|
-
|
|
62
|
-
log.info(f"log_pre_api_call({hex(self.span.context.span_id)[2:]})")
|
|
63
|
-
|
|
64
|
-
self.span.set_attributes(
|
|
65
|
-
attributes={"inputs": {"messages": kwargs["messages"]}},
|
|
66
|
-
namespace="data",
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
self.span.set_attributes(
|
|
70
|
-
attributes={
|
|
71
|
-
"configuration": {
|
|
72
|
-
"model": kwargs.get("model"),
|
|
73
|
-
**kwargs.get("optional_params"),
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
namespace="meta",
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
def log_stream_event(
|
|
80
|
-
self,
|
|
81
|
-
kwargs,
|
|
82
|
-
response_obj,
|
|
83
|
-
start_time,
|
|
84
|
-
end_time,
|
|
85
|
-
):
|
|
86
|
-
if not self.span:
|
|
87
|
-
log.error("LiteLLM callback error: span not found.")
|
|
88
|
-
return
|
|
89
|
-
|
|
90
|
-
# log.info(f"log_stream({hex(self.span.context.span_id)[2:]})")
|
|
91
|
-
|
|
92
|
-
self.span.set_attributes(
|
|
93
|
-
attributes={
|
|
94
|
-
"output": {"__default__": kwargs.get("complete_streaming_response")}
|
|
95
|
-
},
|
|
96
|
-
namespace="data",
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
self.span.set_attributes(
|
|
100
|
-
attributes={"total": kwargs.get("response_cost")},
|
|
101
|
-
namespace="metrics.unit.costs",
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
self.span.set_attributes(
|
|
105
|
-
attributes=(
|
|
106
|
-
{
|
|
107
|
-
"prompt": response_obj.usage.prompt_tokens,
|
|
108
|
-
"completion": response_obj.usage.completion_tokens,
|
|
109
|
-
"total": response_obj.usage.total_tokens,
|
|
110
|
-
}
|
|
111
|
-
),
|
|
112
|
-
namespace="metrics.unit.tokens",
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
self.span.set_status(status="OK")
|
|
116
|
-
|
|
117
|
-
self.span.end()
|
|
118
|
-
|
|
119
|
-
def log_success_event(
|
|
120
|
-
self,
|
|
121
|
-
kwargs,
|
|
122
|
-
response_obj,
|
|
123
|
-
start_time,
|
|
124
|
-
end_time,
|
|
125
|
-
):
|
|
126
|
-
if not self.span:
|
|
127
|
-
log.error("LiteLLM callback error: span not found.")
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
# log.info(f"log_success({hex(self.span.context.span_id)[2:]})")
|
|
131
|
-
|
|
132
|
-
self.span.set_attributes(
|
|
133
|
-
attributes={
|
|
134
|
-
"output": {"__default__": response_obj.choices[0].message.content}
|
|
135
|
-
},
|
|
136
|
-
namespace="data",
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
self.span.set_attributes(
|
|
140
|
-
attributes={"total": kwargs.get("response_cost")},
|
|
141
|
-
namespace="metrics.unit.costs",
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
self.span.set_attributes(
|
|
145
|
-
attributes=(
|
|
146
|
-
{
|
|
147
|
-
"prompt": response_obj.usage.prompt_tokens,
|
|
148
|
-
"completion": response_obj.usage.completion_tokens,
|
|
149
|
-
"total": response_obj.usage.total_tokens,
|
|
150
|
-
}
|
|
151
|
-
),
|
|
152
|
-
namespace="metrics.unit.tokens",
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
self.span.set_status(status="OK")
|
|
156
|
-
|
|
157
|
-
self.span.end()
|
|
158
|
-
|
|
159
|
-
def log_failure_event(
|
|
160
|
-
self,
|
|
161
|
-
kwargs,
|
|
162
|
-
response_obj,
|
|
163
|
-
start_time,
|
|
164
|
-
end_time,
|
|
165
|
-
):
|
|
166
|
-
if not self.span:
|
|
167
|
-
log.error("LiteLLM callback error: span not found.")
|
|
168
|
-
return
|
|
169
|
-
|
|
170
|
-
# log.info(f"log_failure({hex(self.span.context.span_id)[2:]})")
|
|
171
|
-
|
|
172
|
-
self.span.record_exception(kwargs["exception"])
|
|
173
|
-
|
|
174
|
-
self.span.set_status(status="ERROR")
|
|
175
|
-
|
|
176
|
-
self.span.end()
|
|
177
|
-
|
|
178
|
-
async def async_log_stream_event(
|
|
179
|
-
self,
|
|
180
|
-
kwargs,
|
|
181
|
-
response_obj,
|
|
182
|
-
start_time,
|
|
183
|
-
end_time,
|
|
184
|
-
):
|
|
185
|
-
if not self.span:
|
|
186
|
-
log.error("LiteLLM callback error: span not found.")
|
|
187
|
-
return
|
|
188
|
-
|
|
189
|
-
# log.info(f"async_log_stream({hex(self.span.context.span_id)[2:]})")
|
|
190
|
-
|
|
191
|
-
self.span.set_attributes(
|
|
192
|
-
attributes={
|
|
193
|
-
"output": {"__default__": kwargs.get("complete_streaming_response")}
|
|
194
|
-
},
|
|
195
|
-
namespace="data",
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
self.span.set_attributes(
|
|
199
|
-
attributes={"total": kwargs.get("response_cost")},
|
|
200
|
-
namespace="metrics.unit.costs",
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
self.span.set_attributes(
|
|
204
|
-
attributes=(
|
|
205
|
-
{
|
|
206
|
-
"prompt": response_obj.usage.prompt_tokens,
|
|
207
|
-
"completion": response_obj.usage.completion_tokens,
|
|
208
|
-
"total": response_obj.usage.total_tokens,
|
|
209
|
-
}
|
|
210
|
-
),
|
|
211
|
-
namespace="metrics.unit.tokens",
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
self.span.set_status(status="OK")
|
|
215
|
-
|
|
216
|
-
self.span.end()
|
|
217
|
-
|
|
218
|
-
async def async_log_success_event(
|
|
219
|
-
self,
|
|
220
|
-
kwargs,
|
|
221
|
-
response_obj,
|
|
222
|
-
start_time,
|
|
223
|
-
end_time,
|
|
224
|
-
):
|
|
225
|
-
if not self.span:
|
|
226
|
-
log.error("LiteLLM callback error: span not found.")
|
|
227
|
-
return
|
|
228
|
-
|
|
229
|
-
log.info(f"async_log_success({hex(self.span.context.span_id)[2:]})")
|
|
230
|
-
|
|
231
|
-
self.span.set_attributes(
|
|
232
|
-
attributes={
|
|
233
|
-
"output": {"__default__": kwargs.get("complete_streaming_response")}
|
|
234
|
-
},
|
|
235
|
-
namespace="data",
|
|
236
|
-
)
|
|
237
|
-
|
|
238
|
-
self.span.set_attributes(
|
|
239
|
-
attributes={"total": kwargs.get("response_cost")},
|
|
240
|
-
namespace="metrics.unit.costs",
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
self.span.set_attributes(
|
|
244
|
-
attributes=(
|
|
245
|
-
{
|
|
246
|
-
"prompt": response_obj.usage.prompt_tokens,
|
|
247
|
-
"completion": response_obj.usage.completion_tokens,
|
|
248
|
-
"total": response_obj.usage.total_tokens,
|
|
249
|
-
}
|
|
250
|
-
),
|
|
251
|
-
namespace="metrics.unit.tokens",
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
self.span.set_status(status="OK")
|
|
255
|
-
|
|
256
|
-
self.span.end()
|
|
257
|
-
|
|
258
|
-
async def async_log_failure_event(
|
|
259
|
-
self,
|
|
260
|
-
kwargs,
|
|
261
|
-
response_obj,
|
|
262
|
-
start_time,
|
|
263
|
-
end_time,
|
|
264
|
-
):
|
|
265
|
-
if not self.span:
|
|
266
|
-
log.error("LiteLLM callback error: span not found.")
|
|
267
|
-
return
|
|
268
|
-
|
|
269
|
-
# log.info(f"async_log_failure({hex(self.span.context.span_id)[2:]})")
|
|
270
|
-
|
|
271
|
-
self.span.record_exception(kwargs["exception"])
|
|
272
|
-
|
|
273
|
-
self.span.set_status(status="ERROR")
|
|
274
|
-
|
|
275
|
-
self.span.end()
|
|
276
|
-
|
|
277
|
-
return LitellmHandler()
|
agenta/sdk/tracing/attributes.py
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
from json import loads, dumps
|
|
2
|
-
from typing import Optional, Union, Sequence, Any, Dict
|
|
3
|
-
|
|
4
|
-
Primitive = Union[str, int, float, bool, bytes]
|
|
5
|
-
PrimitivesSequence = Sequence[Primitive]
|
|
6
|
-
Attribute = Union[Primitive, PrimitivesSequence]
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def _marshal(
|
|
10
|
-
unmarshalled: Dict[str, Any],
|
|
11
|
-
*,
|
|
12
|
-
parent_key: Optional[str] = "",
|
|
13
|
-
depth: Optional[int] = 0,
|
|
14
|
-
max_depth: Optional[int] = None,
|
|
15
|
-
) -> Dict[str, Any]:
|
|
16
|
-
"""
|
|
17
|
-
Marshals a dictionary of unmarshalled attributes into a flat dictionary
|
|
18
|
-
|
|
19
|
-
Example:
|
|
20
|
-
unmarshalled = {
|
|
21
|
-
"ag": {
|
|
22
|
-
"type": "tree",
|
|
23
|
-
"node": {
|
|
24
|
-
"name": "root",
|
|
25
|
-
"children": [
|
|
26
|
-
{
|
|
27
|
-
"name": "child1",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"name": "child2",
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
marshalled = {
|
|
37
|
-
"ag.type": "tree",
|
|
38
|
-
"ag.node.name": "root",
|
|
39
|
-
"ag.node.children.0.name": "child1",
|
|
40
|
-
"ag.node.children.1.name": "child2"
|
|
41
|
-
}
|
|
42
|
-
"""
|
|
43
|
-
marshalled = {}
|
|
44
|
-
|
|
45
|
-
# If max_depth is set and we've reached it,
|
|
46
|
-
# just return the unmarshalled attributes
|
|
47
|
-
if max_depth is not None and depth >= max_depth:
|
|
48
|
-
marshalled[parent_key] = unmarshalled
|
|
49
|
-
# MISSING ENCODING TO JSON IF NOT PRIMITIVE
|
|
50
|
-
|
|
51
|
-
return marshalled
|
|
52
|
-
|
|
53
|
-
# Otherwise,
|
|
54
|
-
# iterate over the unmarshalled attributes and marshall them
|
|
55
|
-
for key, value in unmarshalled.items():
|
|
56
|
-
child_key = f"{parent_key}.{key}" if parent_key else key
|
|
57
|
-
|
|
58
|
-
if isinstance(value, dict):
|
|
59
|
-
dict_key = child_key
|
|
60
|
-
|
|
61
|
-
marshalled.update(
|
|
62
|
-
_marshal(
|
|
63
|
-
value,
|
|
64
|
-
parent_key=dict_key,
|
|
65
|
-
depth=depth + 1,
|
|
66
|
-
max_depth=max_depth,
|
|
67
|
-
)
|
|
68
|
-
)
|
|
69
|
-
elif isinstance(value, list):
|
|
70
|
-
if max_depth is not None and depth + 1 >= max_depth:
|
|
71
|
-
marshalled[child_key] = value
|
|
72
|
-
# MISSING ENCODING TO JSON IF NOT PRIMITIVE
|
|
73
|
-
else:
|
|
74
|
-
for i, item in enumerate(value):
|
|
75
|
-
list_key = f"{child_key}.{i}"
|
|
76
|
-
|
|
77
|
-
if isinstance(item, (dict, list)):
|
|
78
|
-
marshalled.update(
|
|
79
|
-
_marshal(
|
|
80
|
-
item,
|
|
81
|
-
parent_key=list_key,
|
|
82
|
-
depth=depth + 1,
|
|
83
|
-
max_depth=max_depth,
|
|
84
|
-
)
|
|
85
|
-
)
|
|
86
|
-
else:
|
|
87
|
-
marshalled[list_key] = item
|
|
88
|
-
# MISSING ENCODING TO JSON IF NOT PRIMITIVE
|
|
89
|
-
else:
|
|
90
|
-
marshalled[child_key] = value
|
|
91
|
-
# MISSING ENCODING TO JSON IF NOT PRIMITIVE
|
|
92
|
-
|
|
93
|
-
return marshalled
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def _encode_key(namespace: Optional[str] = None, key: str = "") -> str:
|
|
97
|
-
if namespace is None:
|
|
98
|
-
return key
|
|
99
|
-
|
|
100
|
-
return f"ag.{namespace}.{key}"
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def _encode_value(value: Any) -> Optional[Attribute]:
|
|
104
|
-
if value is None:
|
|
105
|
-
return None
|
|
106
|
-
|
|
107
|
-
if isinstance(value, (str, int, float, bool, bytes)):
|
|
108
|
-
return value
|
|
109
|
-
|
|
110
|
-
if isinstance(value, dict) or isinstance(value, list):
|
|
111
|
-
encoded = dumps(value)
|
|
112
|
-
value = "@ag.type=json:" + encoded
|
|
113
|
-
return value
|
|
114
|
-
|
|
115
|
-
return repr(value)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def serialize(
|
|
119
|
-
*,
|
|
120
|
-
namespace: str,
|
|
121
|
-
attributes: Dict[str, Any],
|
|
122
|
-
max_depth: Optional[int] = None,
|
|
123
|
-
) -> Dict[str, str]:
|
|
124
|
-
if not isinstance(attributes, dict):
|
|
125
|
-
return {}
|
|
126
|
-
|
|
127
|
-
_attributes = {
|
|
128
|
-
k: v
|
|
129
|
-
for k, v in {
|
|
130
|
-
_encode_key(namespace, key): _encode_value(value)
|
|
131
|
-
for key, value in _marshal(attributes, max_depth=max_depth).items()
|
|
132
|
-
}.items()
|
|
133
|
-
if v is not None
|
|
134
|
-
}
|
|
135
|
-
|
|
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
|
-
"""
|
agenta/sdk/tracing/context.py
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
from contextvars import ContextVar
|
|
2
|
-
from contextlib import contextmanager
|
|
3
|
-
from traceback import format_exc
|
|
4
|
-
|
|
5
|
-
from agenta.sdk.utils.logging import log
|
|
6
|
-
|
|
7
|
-
tracing_context = ContextVar("tracing_context", default={})
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@contextmanager
|
|
11
|
-
def tracing_context_manager():
|
|
12
|
-
_tracing_context = {"health": {"status": "ok"}}
|
|
13
|
-
|
|
14
|
-
token = tracing_context.set(_tracing_context)
|
|
15
|
-
try:
|
|
16
|
-
yield
|
|
17
|
-
except Exception as e:
|
|
18
|
-
log.error(f"Error with tracing context: {_tracing_context}")
|
|
19
|
-
log.error(f"Exception: {format_exc()}")
|
|
20
|
-
finally:
|
|
21
|
-
tracing_context.reset(token)
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
from typing import Literal
|
|
2
|
-
|
|
3
|
-
from opentelemetry.trace import SpanKind
|
|
4
|
-
|
|
5
|
-
Namespace = Literal[
|
|
6
|
-
"data.inputs",
|
|
7
|
-
"data.internals",
|
|
8
|
-
"data.outputs",
|
|
9
|
-
"metrics.scores",
|
|
10
|
-
"metrics.unit.costs",
|
|
11
|
-
"metrics.unit.tokens",
|
|
12
|
-
"meta.configuration",
|
|
13
|
-
"meta.version",
|
|
14
|
-
"tags",
|
|
15
|
-
"refs",
|
|
16
|
-
]
|
|
17
|
-
|
|
18
|
-
Code = Literal[
|
|
19
|
-
"OK",
|
|
20
|
-
"UNSET",
|
|
21
|
-
"ERROR",
|
|
22
|
-
]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def parse_span_kind(type: str) -> SpanKind:
|
|
26
|
-
kind = SpanKind.INTERNAL
|
|
27
|
-
if type in [
|
|
28
|
-
"agent",
|
|
29
|
-
"chain",
|
|
30
|
-
"workflow",
|
|
31
|
-
]:
|
|
32
|
-
kind = SpanKind.SERVER
|
|
33
|
-
elif type in [
|
|
34
|
-
"tool",
|
|
35
|
-
"embedding",
|
|
36
|
-
"query",
|
|
37
|
-
"completion",
|
|
38
|
-
"chat",
|
|
39
|
-
"rerank",
|
|
40
|
-
]:
|
|
41
|
-
kind = SpanKind.CLIENT
|
|
42
|
-
|
|
43
|
-
return kind
|
agenta/sdk/tracing/exporters.py
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
from typing import Sequence, Dict, List
|
|
2
|
-
|
|
3
|
-
from opentelemetry.sdk.trace.export import (
|
|
4
|
-
ConsoleSpanExporter,
|
|
5
|
-
SpanExporter,
|
|
6
|
-
SpanExportResult,
|
|
7
|
-
ReadableSpan,
|
|
8
|
-
)
|
|
9
|
-
from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
|
|
10
|
-
OTLPSpanExporter,
|
|
11
|
-
)
|
|
12
|
-
|
|
13
|
-
from agenta.sdk.utils.exceptions import suppress
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class InlineTraceExporter(SpanExporter):
|
|
17
|
-
def __init__(self, registry: Dict[str, List[ReadableSpan]]):
|
|
18
|
-
self._shutdown = False
|
|
19
|
-
self._registry = registry
|
|
20
|
-
|
|
21
|
-
def export(
|
|
22
|
-
self,
|
|
23
|
-
spans: Sequence[ReadableSpan],
|
|
24
|
-
) -> SpanExportResult:
|
|
25
|
-
if self._shutdown:
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
with suppress():
|
|
29
|
-
for span in spans:
|
|
30
|
-
trace_id = span.get_span_context().trace_id
|
|
31
|
-
|
|
32
|
-
if trace_id not in self._registry:
|
|
33
|
-
self._registry[trace_id] = []
|
|
34
|
-
|
|
35
|
-
self._registry[trace_id].append(span)
|
|
36
|
-
|
|
37
|
-
def shutdown(self) -> None:
|
|
38
|
-
self._shutdown = True
|
|
39
|
-
|
|
40
|
-
def force_flush(self, timeout_millis: int = 30000) -> bool:
|
|
41
|
-
return True
|
|
42
|
-
|
|
43
|
-
def fetch(self, trace_id: int) -> List[ReadableSpan]:
|
|
44
|
-
trace = self._registry.get(trace_id, [])
|
|
45
|
-
|
|
46
|
-
del self._registry[trace_id]
|
|
47
|
-
|
|
48
|
-
return trace
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
ConsoleExporter = ConsoleSpanExporter
|
|
52
|
-
InlineExporter = InlineTraceExporter
|
|
53
|
-
OTLPExporter = OTLPSpanExporter
|