agenta 0.20.0a0__py3-none-any.whl → 0.20.0a3__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/client/backend/resources/observability/client.py +11 -0
- agenta/client/backend/types/span.py +1 -1
- agenta/client/backend/types/span_detail.py +1 -1
- agenta/client/backend/types/trace_detail.py +1 -1
- agenta/sdk/agenta_init.py +6 -0
- agenta/sdk/decorators/llm_entrypoint.py +49 -7
- agenta/sdk/decorators/tracing.py +32 -2
- agenta/sdk/tracing/callbacks.py +43 -14
- agenta/sdk/tracing/llm_tracing.py +83 -65
- agenta/sdk/tracing/tracing_context.py +0 -4
- {agenta-0.20.0a0.dist-info → agenta-0.20.0a3.dist-info}/METADATA +1 -1
- {agenta-0.20.0a0.dist-info → agenta-0.20.0a3.dist-info}/RECORD +14 -14
- {agenta-0.20.0a0.dist-info → agenta-0.20.0a3.dist-info}/WHEEL +0 -0
- {agenta-0.20.0a0.dist-info → agenta-0.20.0a3.dist-info}/entry_points.txt +0 -0
|
@@ -17,6 +17,9 @@ from ...types.span_detail import SpanDetail
|
|
|
17
17
|
from ...types.trace_detail import TraceDetail
|
|
18
18
|
from ...types.with_pagination import WithPagination
|
|
19
19
|
|
|
20
|
+
from agenta.sdk.tracing.logger import llm_logger as logging
|
|
21
|
+
|
|
22
|
+
|
|
20
23
|
try:
|
|
21
24
|
import pydantic.v1 as pydantic # type: ignore
|
|
22
25
|
except ImportError:
|
|
@@ -769,6 +772,14 @@ class AsyncObservabilityClient:
|
|
|
769
772
|
],
|
|
770
773
|
)
|
|
771
774
|
"""
|
|
775
|
+
|
|
776
|
+
logging.debug("----")
|
|
777
|
+
logging.debug(
|
|
778
|
+
urllib.parse.urljoin(
|
|
779
|
+
f"{self._client_wrapper.get_base_url()}/", "observability/trace/"
|
|
780
|
+
),
|
|
781
|
+
)
|
|
782
|
+
logging.debug(self._client_wrapper.get_headers())
|
|
772
783
|
_response = await self._client_wrapper.httpx_client.request(
|
|
773
784
|
"POST",
|
|
774
785
|
urllib.parse.urljoin(
|
|
@@ -22,7 +22,7 @@ class SpanDetail(pydantic.BaseModel):
|
|
|
22
22
|
created_at: dt.datetime
|
|
23
23
|
variant: SpanVariant
|
|
24
24
|
environment: typing.Optional[str]
|
|
25
|
-
spankind:
|
|
25
|
+
spankind: str
|
|
26
26
|
status: SpanStatusCode
|
|
27
27
|
metadata: typing.Dict[str, typing.Any]
|
|
28
28
|
user_id: typing.Optional[str]
|
|
@@ -22,7 +22,7 @@ class TraceDetail(pydantic.BaseModel):
|
|
|
22
22
|
created_at: dt.datetime
|
|
23
23
|
variant: SpanVariant
|
|
24
24
|
environment: typing.Optional[str]
|
|
25
|
-
spankind:
|
|
25
|
+
spankind: str
|
|
26
26
|
status: SpanStatusCode
|
|
27
27
|
metadata: typing.Dict[str, typing.Any]
|
|
28
28
|
user_id: typing.Optional[str]
|
agenta/sdk/agenta_init.py
CHANGED
|
@@ -68,6 +68,12 @@ class AgentaSingleton:
|
|
|
68
68
|
api_key or config.get("api_key") or os.environ.get("AGENTA_API_KEY")
|
|
69
69
|
)
|
|
70
70
|
|
|
71
|
+
print(api_key)
|
|
72
|
+
print(config.get("api_key"))
|
|
73
|
+
print(os.environ.get("AGENTA_API_KEY"))
|
|
74
|
+
print(self.api_key)
|
|
75
|
+
print(os.environ)
|
|
76
|
+
|
|
71
77
|
if not self.app_id:
|
|
72
78
|
raise ValueError(
|
|
73
79
|
"App ID must be specified. You can provide it in one of the following ways:\n"
|
|
@@ -141,7 +141,11 @@ class entrypoint(BaseDecorator):
|
|
|
141
141
|
)
|
|
142
142
|
|
|
143
143
|
entrypoint_result = await self.execute_function(
|
|
144
|
-
func,
|
|
144
|
+
func,
|
|
145
|
+
True, # inline trace: True
|
|
146
|
+
*args,
|
|
147
|
+
params=func_params,
|
|
148
|
+
config_params=config_params,
|
|
145
149
|
)
|
|
146
150
|
|
|
147
151
|
return entrypoint_result
|
|
@@ -194,7 +198,11 @@ class entrypoint(BaseDecorator):
|
|
|
194
198
|
)
|
|
195
199
|
|
|
196
200
|
entrypoint_result = await self.execute_function(
|
|
197
|
-
func,
|
|
201
|
+
func,
|
|
202
|
+
False, # inline trace: False
|
|
203
|
+
*args,
|
|
204
|
+
params=func_params,
|
|
205
|
+
config_params=config_params,
|
|
198
206
|
)
|
|
199
207
|
|
|
200
208
|
return entrypoint_result
|
|
@@ -205,7 +213,7 @@ class entrypoint(BaseDecorator):
|
|
|
205
213
|
ingestible_files,
|
|
206
214
|
)
|
|
207
215
|
|
|
208
|
-
if route_path == "
|
|
216
|
+
if route_path == "":
|
|
209
217
|
route_deployed = f"/{DEFAULT_PATH}_deployed"
|
|
210
218
|
app.post(route_deployed, response_model=BaseResponse)(wrapper_deployed)
|
|
211
219
|
|
|
@@ -226,6 +234,8 @@ class entrypoint(BaseDecorator):
|
|
|
226
234
|
)
|
|
227
235
|
### ---------------------- #
|
|
228
236
|
|
|
237
|
+
print(entrypoint.routes)
|
|
238
|
+
|
|
229
239
|
if self.is_main_script(func) and route_path == "":
|
|
230
240
|
self.handle_terminal_run(
|
|
231
241
|
func,
|
|
@@ -272,7 +282,9 @@ class entrypoint(BaseDecorator):
|
|
|
272
282
|
if name in func_params and func_params[name] is not None:
|
|
273
283
|
func_params[name] = self.ingest_file(func_params[name])
|
|
274
284
|
|
|
275
|
-
async def execute_function(
|
|
285
|
+
async def execute_function(
|
|
286
|
+
self, func: Callable[..., Any], inline_trace, *args, **func_params
|
|
287
|
+
):
|
|
276
288
|
"""Execute the function and handle any exceptions."""
|
|
277
289
|
|
|
278
290
|
try:
|
|
@@ -281,6 +293,11 @@ class entrypoint(BaseDecorator):
|
|
|
281
293
|
For synchronous functions, it calls them directly, while for asynchronous functions,
|
|
282
294
|
it awaits their execution.
|
|
283
295
|
"""
|
|
296
|
+
WAIT_FOR_SPANS = True
|
|
297
|
+
TIMEOUT = 10
|
|
298
|
+
TIMESTEP = 0.01
|
|
299
|
+
NOFSTEPS = TIMEOUT / TIMESTEP
|
|
300
|
+
|
|
284
301
|
data = None
|
|
285
302
|
trace = None
|
|
286
303
|
|
|
@@ -296,18 +313,41 @@ class entrypoint(BaseDecorator):
|
|
|
296
313
|
result = func(*args, **func_params["params"])
|
|
297
314
|
|
|
298
315
|
if token is not None:
|
|
316
|
+
if WAIT_FOR_SPANS:
|
|
317
|
+
remaining_steps = NOFSTEPS
|
|
318
|
+
|
|
319
|
+
while not ag.tracing.is_trace_ready() and remaining_steps > 0:
|
|
320
|
+
await asyncio.sleep(0.01)
|
|
321
|
+
remaining_steps -= 1
|
|
322
|
+
|
|
299
323
|
trace = ag.tracing.dump_trace()
|
|
324
|
+
|
|
325
|
+
if not inline_trace:
|
|
326
|
+
trace = {"trace_id": trace["trace_id"]}
|
|
327
|
+
|
|
328
|
+
ag.tracing.flush_spans()
|
|
300
329
|
tracing_context.reset(token)
|
|
301
330
|
|
|
302
331
|
if isinstance(result, Context):
|
|
303
332
|
save_context(result)
|
|
304
333
|
|
|
334
|
+
DEFAULT_KEY = "message"
|
|
335
|
+
|
|
305
336
|
if isinstance(result, Dict):
|
|
306
337
|
data = result
|
|
338
|
+
|
|
339
|
+
# EVENTUALLY THIS PATCH SHOULD BE REMOVED
|
|
340
|
+
# PATCH: if message in result then only keep message key/value
|
|
341
|
+
# DEFAULT_KEY = "message"
|
|
342
|
+
|
|
343
|
+
if "message" in result.keys():
|
|
344
|
+
data = {DEFAULT_KEY: result["message"]}
|
|
345
|
+
# END OF PATCH
|
|
346
|
+
|
|
307
347
|
elif isinstance(result, str):
|
|
308
|
-
data = {
|
|
348
|
+
data = {DEFAULT_KEY: result}
|
|
309
349
|
elif isinstance(result, int) or isinstance(result, float):
|
|
310
|
-
data = {
|
|
350
|
+
data = {DEFAULT_KEY: str(result)}
|
|
311
351
|
|
|
312
352
|
if data is None:
|
|
313
353
|
warning = (
|
|
@@ -515,6 +555,7 @@ class entrypoint(BaseDecorator):
|
|
|
515
555
|
result = loop.run_until_complete(
|
|
516
556
|
self.execute_function(
|
|
517
557
|
func,
|
|
558
|
+
True, # inline trace: True
|
|
518
559
|
**{"params": args_func_params, "config_params": args_config_params},
|
|
519
560
|
)
|
|
520
561
|
)
|
|
@@ -524,7 +565,7 @@ class entrypoint(BaseDecorator):
|
|
|
524
565
|
print("-> data")
|
|
525
566
|
print(json.dumps(result.data, indent=2))
|
|
526
567
|
print("-> trace")
|
|
527
|
-
print(json.dumps(result.trace, indent=2))
|
|
568
|
+
# print(json.dumps(result.trace, indent=2))
|
|
528
569
|
|
|
529
570
|
def override_schema(
|
|
530
571
|
self, openapi_schema: dict, func: str, endpoint: str, params: dict
|
|
@@ -598,6 +639,7 @@ class entrypoint(BaseDecorator):
|
|
|
598
639
|
schema_to_override = openapi_schema["components"]["schemas"][
|
|
599
640
|
f"Body_{func}_{endpoint}_post"
|
|
600
641
|
]["properties"]
|
|
642
|
+
|
|
601
643
|
for param_name, param_val in params.items():
|
|
602
644
|
if isinstance(param_val, GroupedMultipleChoiceParam):
|
|
603
645
|
subschema = find_in_schema(
|
agenta/sdk/decorators/tracing.py
CHANGED
|
@@ -65,7 +65,22 @@ class instrument(BaseDecorator):
|
|
|
65
65
|
):
|
|
66
66
|
result = await func(*args, **kwargs)
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
outputs = result
|
|
69
|
+
|
|
70
|
+
# EVENTUALLY THIS PATCH SHOULD BE REMOVED
|
|
71
|
+
# PATCH : if result is not a dict, make it a dict, in span
|
|
72
|
+
DEFAULT_KEY = "default"
|
|
73
|
+
|
|
74
|
+
if not isinstance(result, dict):
|
|
75
|
+
value = result
|
|
76
|
+
|
|
77
|
+
if result.__class__.__module__ != "__builtin__":
|
|
78
|
+
value = repr(value)
|
|
79
|
+
|
|
80
|
+
outputs = {DEFAULT_KEY: result}
|
|
81
|
+
# END OF PATH
|
|
82
|
+
|
|
83
|
+
ag.tracing.store_outputs(outputs)
|
|
69
84
|
|
|
70
85
|
return result
|
|
71
86
|
|
|
@@ -82,7 +97,22 @@ class instrument(BaseDecorator):
|
|
|
82
97
|
):
|
|
83
98
|
result = func(*args, **kwargs)
|
|
84
99
|
|
|
85
|
-
|
|
100
|
+
outputs = result
|
|
101
|
+
|
|
102
|
+
# EVENTUALLY THIS PATCH SHOULD BE REMOVED
|
|
103
|
+
# PATCH : if result is not a dict, make it a dict, in span
|
|
104
|
+
DEFAULT_KEY = "default"
|
|
105
|
+
|
|
106
|
+
if not isinstance(result, dict):
|
|
107
|
+
value = result
|
|
108
|
+
|
|
109
|
+
if result.__class__.__module__ != "__builtin__":
|
|
110
|
+
value = repr(value)
|
|
111
|
+
|
|
112
|
+
outputs = {DEFAULT_KEY: result}
|
|
113
|
+
# END OF PATH
|
|
114
|
+
|
|
115
|
+
ag.tracing.store_outputs(outputs)
|
|
86
116
|
|
|
87
117
|
return result
|
|
88
118
|
|
agenta/sdk/tracing/callbacks.py
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import agenta as ag
|
|
2
2
|
|
|
3
|
+
from agenta.sdk.tracing.tracing_context import tracing_context, TracingContext
|
|
4
|
+
|
|
5
|
+
from agenta.sdk.utils.debug import debug
|
|
6
|
+
|
|
3
7
|
|
|
4
8
|
def litellm_handler():
|
|
5
9
|
try:
|
|
@@ -23,20 +27,25 @@ def litellm_handler():
|
|
|
23
27
|
LitellmCustomLogger (object): custom logger that allows us to override the events to capture.
|
|
24
28
|
"""
|
|
25
29
|
|
|
30
|
+
def __init__(self):
|
|
31
|
+
self.span = None
|
|
32
|
+
|
|
26
33
|
@property
|
|
27
34
|
def _trace(self):
|
|
28
35
|
return ag.tracing
|
|
29
36
|
|
|
37
|
+
@debug()
|
|
30
38
|
def log_pre_api_call(self, model, messages, kwargs):
|
|
31
39
|
call_type = kwargs.get("call_type")
|
|
32
40
|
span_kind = (
|
|
33
41
|
"llm" if call_type in ["completion", "acompletion"] else "embedding"
|
|
34
42
|
)
|
|
35
43
|
|
|
36
|
-
ag.tracing.
|
|
44
|
+
self.span = ag.tracing.open_span(
|
|
37
45
|
name=f"{span_kind}_call",
|
|
38
46
|
input={"messages": kwargs["messages"]},
|
|
39
47
|
spankind=span_kind,
|
|
48
|
+
active=False,
|
|
40
49
|
)
|
|
41
50
|
ag.tracing.set_attributes(
|
|
42
51
|
{
|
|
@@ -49,9 +58,10 @@ def litellm_handler():
|
|
|
49
58
|
}
|
|
50
59
|
)
|
|
51
60
|
|
|
61
|
+
@debug()
|
|
52
62
|
def log_stream_event(self, kwargs, response_obj, start_time, end_time):
|
|
53
|
-
ag.tracing.set_status(status="OK")
|
|
54
|
-
ag.tracing.
|
|
63
|
+
ag.tracing.set_status(status="OK", span_id=self.span.id)
|
|
64
|
+
ag.tracing.store_outputs(
|
|
55
65
|
outputs={
|
|
56
66
|
"message": kwargs.get(
|
|
57
67
|
"complete_streaming_response"
|
|
@@ -65,13 +75,16 @@ def litellm_handler():
|
|
|
65
75
|
"response_cost"
|
|
66
76
|
), # litellm calculates response cost
|
|
67
77
|
},
|
|
78
|
+
span_id=self.span.id,
|
|
68
79
|
)
|
|
80
|
+
ag.tracing.close_span(span_id=self.span.id)
|
|
69
81
|
|
|
82
|
+
@debug()
|
|
70
83
|
def log_success_event(
|
|
71
84
|
self, kwargs, response_obj: ModelResponse, start_time, end_time
|
|
72
85
|
):
|
|
73
|
-
ag.tracing.set_status(status="OK")
|
|
74
|
-
ag.tracing.
|
|
86
|
+
ag.tracing.set_status(status="OK", span_id=self.span.id)
|
|
87
|
+
ag.tracing.store_outputs(
|
|
75
88
|
outputs={
|
|
76
89
|
"message": response_obj.choices[0].message.content,
|
|
77
90
|
"usage": (
|
|
@@ -83,12 +96,15 @@ def litellm_handler():
|
|
|
83
96
|
"response_cost"
|
|
84
97
|
), # litellm calculates response cost
|
|
85
98
|
},
|
|
99
|
+
span_id=self.span.id,
|
|
86
100
|
)
|
|
101
|
+
ag.tracing.close_span(span_id=self.span.id)
|
|
87
102
|
|
|
103
|
+
@debug()
|
|
88
104
|
def log_failure_event(
|
|
89
105
|
self, kwargs, response_obj: ModelResponse, start_time, end_time
|
|
90
106
|
):
|
|
91
|
-
ag.tracing.set_status(status="ERROR")
|
|
107
|
+
ag.tracing.set_status(status="ERROR", span_id=self.span.id)
|
|
92
108
|
ag.tracing.set_attributes(
|
|
93
109
|
{
|
|
94
110
|
"traceback_exception": repr(
|
|
@@ -98,10 +114,11 @@ def litellm_handler():
|
|
|
98
114
|
"end_time"
|
|
99
115
|
], # datetime object of when call was completed
|
|
100
116
|
},
|
|
117
|
+
span_id=self.span.id,
|
|
101
118
|
)
|
|
102
|
-
ag.tracing.
|
|
119
|
+
ag.tracing.store_outputs(
|
|
103
120
|
outputs={
|
|
104
|
-
"message": kwargs["exception"], # the Exception raised
|
|
121
|
+
"message": repr(kwargs["exception"]), # the Exception raised
|
|
105
122
|
"usage": (
|
|
106
123
|
response_obj.usage.dict()
|
|
107
124
|
if hasattr(response_obj, "usage")
|
|
@@ -111,13 +128,16 @@ def litellm_handler():
|
|
|
111
128
|
"response_cost"
|
|
112
129
|
), # litellm calculates response cost
|
|
113
130
|
},
|
|
131
|
+
span_id=self.span.id,
|
|
114
132
|
)
|
|
133
|
+
ag.tracing.close_span(span_id=self.span.id)
|
|
115
134
|
|
|
135
|
+
@debug()
|
|
116
136
|
async def async_log_stream_event(
|
|
117
137
|
self, kwargs, response_obj, start_time, end_time
|
|
118
138
|
):
|
|
119
|
-
ag.tracing.set_status(status="OK")
|
|
120
|
-
ag.tracing.
|
|
139
|
+
ag.tracing.set_status(status="OK", span_id=self.span.id)
|
|
140
|
+
ag.tracing.store_outputs(
|
|
121
141
|
outputs={
|
|
122
142
|
"message": kwargs.get(
|
|
123
143
|
"complete_streaming_response"
|
|
@@ -131,13 +151,16 @@ def litellm_handler():
|
|
|
131
151
|
"response_cost"
|
|
132
152
|
), # litellm calculates response cost
|
|
133
153
|
},
|
|
154
|
+
span_id=self.span.id,
|
|
134
155
|
)
|
|
156
|
+
ag.tracing.close_span(span_id=self.span.id)
|
|
135
157
|
|
|
158
|
+
@debug()
|
|
136
159
|
async def async_log_success_event(
|
|
137
160
|
self, kwargs, response_obj, start_time, end_time
|
|
138
161
|
):
|
|
139
|
-
ag.tracing.set_status(status="OK")
|
|
140
|
-
ag.tracing.
|
|
162
|
+
ag.tracing.set_status(status="OK", span_id=self.span.id)
|
|
163
|
+
ag.tracing.store_outputs(
|
|
141
164
|
outputs={
|
|
142
165
|
"message": response_obj.choices[0].message.content,
|
|
143
166
|
"usage": (
|
|
@@ -149,12 +172,15 @@ def litellm_handler():
|
|
|
149
172
|
"response_cost"
|
|
150
173
|
), # litellm calculates response cost
|
|
151
174
|
},
|
|
175
|
+
span_id=self.span.id,
|
|
152
176
|
)
|
|
177
|
+
ag.tracing.close_span(span_id=self.span.id)
|
|
153
178
|
|
|
179
|
+
@debug()
|
|
154
180
|
async def async_log_failure_event(
|
|
155
181
|
self, kwargs, response_obj, start_time, end_time
|
|
156
182
|
):
|
|
157
|
-
ag.tracing.set_status(status="ERROR")
|
|
183
|
+
ag.tracing.set_status(status="ERROR", span_id=self.span.id)
|
|
158
184
|
ag.tracing.set_attributes(
|
|
159
185
|
{
|
|
160
186
|
"traceback_exception": kwargs[
|
|
@@ -164,8 +190,9 @@ def litellm_handler():
|
|
|
164
190
|
"end_time"
|
|
165
191
|
], # datetime object of when call was completed
|
|
166
192
|
},
|
|
193
|
+
span_id=self.span.id,
|
|
167
194
|
)
|
|
168
|
-
ag.tracing.
|
|
195
|
+
ag.tracing.store_outputs(
|
|
169
196
|
outputs={
|
|
170
197
|
"message": repr(kwargs["exception"]), # the Exception raised
|
|
171
198
|
"usage": (
|
|
@@ -177,6 +204,8 @@ def litellm_handler():
|
|
|
177
204
|
"response_cost"
|
|
178
205
|
), # litellm calculates response cost
|
|
179
206
|
},
|
|
207
|
+
span_id=self.span.id,
|
|
180
208
|
)
|
|
209
|
+
ag.tracing.close_span(span_id=self.span.id)
|
|
181
210
|
|
|
182
211
|
return LitellmHandler()
|
|
@@ -25,7 +25,7 @@ from bson.objectid import ObjectId
|
|
|
25
25
|
|
|
26
26
|
VARIANT_TRACKING_FEATURE_FLAG = False
|
|
27
27
|
|
|
28
|
-
from agenta.sdk.utils.debug import debug
|
|
28
|
+
from agenta.sdk.utils.debug import debug
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
logging.setLevel("DEBUG")
|
|
@@ -195,6 +195,14 @@ class Tracing(metaclass=SingletonMeta):
|
|
|
195
195
|
|
|
196
196
|
tracing.trace_tags.extend(tags)
|
|
197
197
|
|
|
198
|
+
@debug()
|
|
199
|
+
def is_trace_ready(self):
|
|
200
|
+
tracing = tracing_context.get()
|
|
201
|
+
|
|
202
|
+
are_spans_ready = [span.end_time is not None for span in tracing.spans.values()]
|
|
203
|
+
|
|
204
|
+
return all(are_spans_ready)
|
|
205
|
+
|
|
198
206
|
@debug()
|
|
199
207
|
def close_trace(self) -> None:
|
|
200
208
|
"""
|
|
@@ -234,6 +242,7 @@ class Tracing(metaclass=SingletonMeta):
|
|
|
234
242
|
name: str,
|
|
235
243
|
spankind: str,
|
|
236
244
|
input: Dict[str, Any],
|
|
245
|
+
active: bool = True,
|
|
237
246
|
config: Optional[Dict[str, Any]] = None,
|
|
238
247
|
**kwargs,
|
|
239
248
|
) -> CreateSpan:
|
|
@@ -270,7 +279,14 @@ class Tracing(metaclass=SingletonMeta):
|
|
|
270
279
|
else:
|
|
271
280
|
span.parent_span_id = tracing.active_span.id # type: ignore
|
|
272
281
|
|
|
273
|
-
tracing.
|
|
282
|
+
tracing.spans[span.id] = span
|
|
283
|
+
|
|
284
|
+
if active:
|
|
285
|
+
tracing.active_span = span
|
|
286
|
+
else:
|
|
287
|
+
# DETACHED SPAN
|
|
288
|
+
pass
|
|
289
|
+
|
|
274
290
|
### --- TO BE CLEANED --- <<<
|
|
275
291
|
|
|
276
292
|
logging.info(f"Opened span {span_id} {spankind.upper()}")
|
|
@@ -279,8 +295,7 @@ class Tracing(metaclass=SingletonMeta):
|
|
|
279
295
|
|
|
280
296
|
@debug(req=True)
|
|
281
297
|
def set_attributes(
|
|
282
|
-
self,
|
|
283
|
-
attributes: Dict[str, Any] = {},
|
|
298
|
+
self, attributes: Dict[str, Any] = {}, span_id: Optional[str] = None
|
|
284
299
|
) -> None:
|
|
285
300
|
"""
|
|
286
301
|
Set attributes for the active span.
|
|
@@ -289,41 +304,31 @@ class Tracing(metaclass=SingletonMeta):
|
|
|
289
304
|
attributes (Dict[str, Any], optional): A dictionary of attributes to set. Defaults to {}.
|
|
290
305
|
"""
|
|
291
306
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
if tracing.active_span is None:
|
|
295
|
-
logging.error(f"Cannot set attributes ({set(attributes)}), no active span")
|
|
296
|
-
return
|
|
307
|
+
span = self._get_target_span(span_id)
|
|
297
308
|
|
|
298
309
|
logging.info(
|
|
299
|
-
f"Setting span {
|
|
310
|
+
f"Setting span {span.id} {span.spankind.upper()} attributes={attributes}"
|
|
300
311
|
)
|
|
301
312
|
|
|
302
313
|
for key, value in attributes.items():
|
|
303
|
-
|
|
314
|
+
span.attributes[key] = value # type: ignore
|
|
304
315
|
|
|
305
316
|
@debug()
|
|
306
|
-
def set_status(self, status: str) -> None:
|
|
317
|
+
def set_status(self, status: str, span_id: Optional[str] = None) -> None:
|
|
307
318
|
"""
|
|
308
319
|
Set status for the active span.
|
|
309
320
|
|
|
310
321
|
Args:
|
|
311
322
|
status: Enum ( UNSET, OK, ERROR )
|
|
312
323
|
"""
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if tracing.active_span is None:
|
|
316
|
-
logging.error(f"Cannot set status ({status}), no active span")
|
|
317
|
-
return
|
|
324
|
+
span = self._get_target_span(span_id)
|
|
318
325
|
|
|
319
|
-
logging.info(
|
|
320
|
-
f"Setting span {tracing.active_span.id} {tracing.active_span.spankind.upper()} status={status}"
|
|
321
|
-
)
|
|
326
|
+
logging.info(f"Setting span {span.id} {span.spankind.upper()} status={status}")
|
|
322
327
|
|
|
323
|
-
|
|
328
|
+
span.status = status
|
|
324
329
|
|
|
325
330
|
@debug()
|
|
326
|
-
def close_span(self) -> None:
|
|
331
|
+
def close_span(self, span_id: Optional[str] = None) -> None:
|
|
327
332
|
"""
|
|
328
333
|
Ends the active span, if it is a parent span, ends the trace too.
|
|
329
334
|
|
|
@@ -340,86 +345,76 @@ class Tracing(metaclass=SingletonMeta):
|
|
|
340
345
|
Returns:
|
|
341
346
|
None
|
|
342
347
|
"""
|
|
348
|
+
span = self._get_target_span(span_id)
|
|
343
349
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if tracing.active_span is None:
|
|
347
|
-
logging.error("Cannot close span, no active span")
|
|
348
|
-
|
|
349
|
-
span_id = tracing.active_span.id
|
|
350
|
-
spankind = tracing.active_span.spankind
|
|
350
|
+
spankind = span.spankind
|
|
351
351
|
|
|
352
|
-
logging.info(f"Closing span {
|
|
352
|
+
logging.info(f"Closing span {span.id} {spankind}")
|
|
353
353
|
|
|
354
354
|
### --- TO BE CLEANED --- >>>
|
|
355
|
-
|
|
355
|
+
span.end_time = datetime.now(timezone.utc)
|
|
356
356
|
|
|
357
357
|
# TODO: Remove this whole part. Setting the cost should be done through set_span_attribute
|
|
358
|
-
if isinstance(
|
|
359
|
-
self._update_span_cost(
|
|
360
|
-
|
|
361
|
-
)
|
|
362
|
-
self._update_span_tokens(
|
|
363
|
-
tracing.active_span, tracing.active_span.outputs.get("usage", None)
|
|
364
|
-
)
|
|
358
|
+
if isinstance(span.outputs, dict):
|
|
359
|
+
self._update_span_cost(span, span.outputs.get("cost", None))
|
|
360
|
+
self._update_span_tokens(span, span.outputs.get("usage", None))
|
|
365
361
|
|
|
366
|
-
|
|
362
|
+
span_parent_id = span.parent_span_id
|
|
367
363
|
|
|
368
|
-
if
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
364
|
+
if span_parent_id is not None:
|
|
365
|
+
tracing = tracing_context.get()
|
|
366
|
+
|
|
367
|
+
parent_span = tracing.spans[span_parent_id]
|
|
368
|
+
self._update_span_cost(parent_span, span.cost)
|
|
369
|
+
self._update_span_tokens(parent_span, span.tokens)
|
|
370
|
+
|
|
371
|
+
if span_id is None:
|
|
372
|
+
tracing.active_span = parent_span
|
|
373
373
|
### --- TO BE CLEANED --- <<<
|
|
374
374
|
|
|
375
375
|
logging.info(f"Closed span {span_id} {spankind}")
|
|
376
376
|
|
|
377
377
|
@debug()
|
|
378
|
-
def store_internals(
|
|
378
|
+
def store_internals(
|
|
379
|
+
self, internals: Dict[str, Any] = {}, span_id: Optional[str] = None
|
|
380
|
+
) -> None:
|
|
379
381
|
"""
|
|
380
382
|
Set internals for the active span.
|
|
381
383
|
|
|
382
384
|
Args:
|
|
383
385
|
internals (Dict[str, Any], optional): A dictionary of local variables to set. Defaults to {}.
|
|
384
386
|
"""
|
|
385
|
-
|
|
386
|
-
tracing = tracing_context.get()
|
|
387
|
-
|
|
388
|
-
if tracing.active_span is None:
|
|
389
|
-
logging.error(f"Cannot set internals ({set(internals)}), no active span")
|
|
390
|
-
return
|
|
387
|
+
span = self._get_target_span(span_id)
|
|
391
388
|
|
|
392
389
|
logging.info(
|
|
393
|
-
f"Setting span {
|
|
390
|
+
f"Setting span {span.id} {span.spankind.upper()} internals={internals}"
|
|
394
391
|
)
|
|
395
392
|
|
|
396
|
-
if
|
|
397
|
-
|
|
393
|
+
if span.internals is None:
|
|
394
|
+
span.internals = dict()
|
|
398
395
|
|
|
399
396
|
for key, value in internals.items():
|
|
400
|
-
|
|
397
|
+
span.internals[key] = value # type: ignore
|
|
401
398
|
|
|
402
399
|
@debug()
|
|
403
|
-
def store_outputs(
|
|
400
|
+
def store_outputs(
|
|
401
|
+
self, outputs: Dict[str, Any] = {}, span_id: Optional[str] = None
|
|
402
|
+
) -> None:
|
|
404
403
|
"""
|
|
405
404
|
Set outputs for the active span.
|
|
406
405
|
|
|
407
406
|
Args:
|
|
408
407
|
outputs (Dict[str, Any], optional): A dictionary of output variables to set. Defaults to {}.
|
|
409
408
|
"""
|
|
410
|
-
|
|
411
|
-
tracing = tracing_context.get()
|
|
412
|
-
|
|
413
|
-
if tracing.active_span is None:
|
|
414
|
-
logging.error(f"Cannot set outputs ({set(outputs)}), no active span")
|
|
415
|
-
return
|
|
409
|
+
span = self._get_target_span(span_id)
|
|
416
410
|
|
|
417
411
|
logging.info(
|
|
418
|
-
f"Setting span {
|
|
412
|
+
f"Setting span {span.id} {span.spankind.upper()} outputs={outputs}"
|
|
419
413
|
)
|
|
420
414
|
|
|
421
|
-
|
|
415
|
+
span.outputs = outputs
|
|
422
416
|
|
|
417
|
+
@debug()
|
|
423
418
|
def dump_trace(self):
|
|
424
419
|
"""
|
|
425
420
|
Collects and organizes tracing information into a dictionary.
|
|
@@ -443,7 +438,10 @@ class Tracing(metaclass=SingletonMeta):
|
|
|
443
438
|
trace["usage"] = (
|
|
444
439
|
None if span.tokens is None else json.loads(span.tokens.json())
|
|
445
440
|
)
|
|
446
|
-
trace["latency"] = (
|
|
441
|
+
trace["latency"] = (
|
|
442
|
+
(span.end_time if span.end_time else span.start_time)
|
|
443
|
+
- span.start_time
|
|
444
|
+
).total_seconds()
|
|
447
445
|
|
|
448
446
|
spans = (
|
|
449
447
|
[]
|
|
@@ -526,6 +524,26 @@ class Tracing(metaclass=SingletonMeta):
|
|
|
526
524
|
# return uuid4().hex[:16]
|
|
527
525
|
return str(ObjectId())
|
|
528
526
|
|
|
527
|
+
def _get_target_span(self, span_id) -> CreateSpan:
|
|
528
|
+
tracing = tracing_context.get()
|
|
529
|
+
|
|
530
|
+
span = None
|
|
531
|
+
|
|
532
|
+
if span_id is None:
|
|
533
|
+
if tracing.active_span is None:
|
|
534
|
+
logging.error(f"Cannot set attributes, no active span")
|
|
535
|
+
return
|
|
536
|
+
|
|
537
|
+
span = tracing.active_span
|
|
538
|
+
else:
|
|
539
|
+
if span_id not in tracing.spans.keys():
|
|
540
|
+
logging.error(f"Cannot set attributes, span ({span_id}) not found")
|
|
541
|
+
return
|
|
542
|
+
|
|
543
|
+
span = tracing.spans[span_id]
|
|
544
|
+
|
|
545
|
+
return span
|
|
546
|
+
|
|
529
547
|
def _process_spans(self) -> None:
|
|
530
548
|
tracing = tracing_context.get()
|
|
531
549
|
|
|
@@ -37,7 +37,7 @@ agenta/client/backend/resources/evaluations/client.py,sha256=T8ETcdUdAMzSA3TGu-C
|
|
|
37
37
|
agenta/client/backend/resources/evaluators/__init__.py,sha256=9mUnTDeA1TxYvkj1l01A1prqsJV0ERRY2tzkY1fA4MQ,64
|
|
38
38
|
agenta/client/backend/resources/evaluators/client.py,sha256=xaafddTNiiPpcxbiUFqimaN3tE6fiemYNOpt1wRLci0,21753
|
|
39
39
|
agenta/client/backend/resources/observability/__init__.py,sha256=9mUnTDeA1TxYvkj1l01A1prqsJV0ERRY2tzkY1fA4MQ,64
|
|
40
|
-
agenta/client/backend/resources/observability/client.py,sha256=
|
|
40
|
+
agenta/client/backend/resources/observability/client.py,sha256=4kTC18reOl0SBdHP7iVLunVPyqOsXq2FFWZYLe5mbU0,43239
|
|
41
41
|
agenta/client/backend/resources/testsets/__init__.py,sha256=9mUnTDeA1TxYvkj1l01A1prqsJV0ERRY2tzkY1fA4MQ,64
|
|
42
42
|
agenta/client/backend/resources/testsets/client.py,sha256=jVRwbUAPPgXoApClHjoDQNeVQTxZWq4c7-CT1YZ7DRA,25010
|
|
43
43
|
agenta/client/backend/resources/variants/__init__.py,sha256=BMR4SvsrqXC9FU8nPVzY8M9xGrBEhEGrmbgvy3iM1aE,171
|
|
@@ -94,8 +94,8 @@ agenta/client/backend/types/permission.py,sha256=MwGwNvKhH8W4I0uJZG_mUydJgwE5CF1
|
|
|
94
94
|
agenta/client/backend/types/result.py,sha256=XEUcohx29Rl8P9KfnygbdbeNcgvPgO6WOZv9bebCVsg,1055
|
|
95
95
|
agenta/client/backend/types/score.py,sha256=OAur_nJtRQmpboZfzFi2l1-zmNxFfETcl13C7OAvpMw,111
|
|
96
96
|
agenta/client/backend/types/simple_evaluation_output.py,sha256=gRLOCps1hhXPgioADjD2DfabNJf9WgmmhPI6lJY00q4,1117
|
|
97
|
-
agenta/client/backend/types/span.py,sha256
|
|
98
|
-
agenta/client/backend/types/span_detail.py,sha256=
|
|
97
|
+
agenta/client/backend/types/span.py,sha256=-TrMb3pnTjcbEeD4NA3STGl6V-VyXQ4de7VOjrjwxf4,1450
|
|
98
|
+
agenta/client/backend/types/span_detail.py,sha256=6x0qsMdFRDRvBQuLo7kdHyoR_vqFtxiVYWvKo4FZLYQ,1514
|
|
99
99
|
agenta/client/backend/types/span_kind.py,sha256=3i1C1U-NzDgFpgw8QL0c7CwHHhejCUpSmq5FD1YHiJI,1324
|
|
100
100
|
agenta/client/backend/types/span_status_code.py,sha256=uxcUEsPLQa2r2eIgYw8LRmMj5GQaE98UnL1JgUsdyuM,643
|
|
101
101
|
agenta/client/backend/types/span_variant.py,sha256=BQIrSv4zCNeUSLK5ad3l3BHoc856jXc-v9yd2oTwOkk,1008
|
|
@@ -103,7 +103,7 @@ agenta/client/backend/types/template.py,sha256=mInivp-YnXqt28mWM9y4zqNezOfvUEPcm
|
|
|
103
103
|
agenta/client/backend/types/template_image_info.py,sha256=BycGLw_7XHl9GWOBpu1eu3I_fSQ3n5UVFQdzC0cQ_v8,1189
|
|
104
104
|
agenta/client/backend/types/test_set_output_response.py,sha256=T1HtKP3y2z5UOvqR4_rpUadr7zfGQUxzXAhXBrsBWCg,1088
|
|
105
105
|
agenta/client/backend/types/test_set_simple_response.py,sha256=YI4tRQodB7-5PsIt4RVb8JwJ16vvsFXo7ed_0iHCoOM,1004
|
|
106
|
-
agenta/client/backend/types/trace_detail.py,sha256=
|
|
106
|
+
agenta/client/backend/types/trace_detail.py,sha256=BCx_GZqus6n5Zl2ZsHMFllXpogh2UUH47NpM23SeFxc,1498
|
|
107
107
|
agenta/client/backend/types/uri.py,sha256=dfnTFYdnqiqBzwKItet51L-UMuyd8hkdTw9g4aGrOjM,953
|
|
108
108
|
agenta/client/backend/types/validation_error.py,sha256=KiHcCQ9smOvyaCnwh9EqD-EfiR24wrczv6p-VDS9p5I,1086
|
|
109
109
|
agenta/client/backend/types/validation_error_loc_item.py,sha256=LAtjCHIllWRBFXvAZ5QZpp7CPXjdtN9EB7HrLVo6EP0,128
|
|
@@ -127,20 +127,20 @@ agenta/docker/docker-assets/lambda_function.py,sha256=h4UZSSfqwpfsCgERv6frqwm_4J
|
|
|
127
127
|
agenta/docker/docker-assets/main.py,sha256=7MI-21n81U7N7A0GxebNi0cmGWtJKcR2sPB6FcH2QfA,251
|
|
128
128
|
agenta/docker/docker_utils.py,sha256=5uHMCzXkCvIsDdEiwbnnn97KkzsFbBvyMwogCsv_Z5U,3509
|
|
129
129
|
agenta/sdk/__init__.py,sha256=ewYNjm6AHlqkIrPfX2D_pXZMwShOdhEUcWXb7xGA2bk,769
|
|
130
|
-
agenta/sdk/agenta_init.py,sha256=
|
|
130
|
+
agenta/sdk/agenta_init.py,sha256=WXsT266BLSr7LeNoYPEmDLNj8qoxPsggge-dto7f_9w,9953
|
|
131
131
|
agenta/sdk/client.py,sha256=trKyBOYFZRk0v5Eptxvh87yPf50Y9CqY6Qgv4Fy-VH4,2142
|
|
132
132
|
agenta/sdk/context.py,sha256=q-PxL05-I84puunUAs9LGsffEXcYhDxhQxjuOz2vK90,901
|
|
133
133
|
agenta/sdk/decorators/base.py,sha256=9aNdX5h8a2mFweuhdO-BQPwXGKY9ONPIdLRhSGAGMfY,217
|
|
134
|
-
agenta/sdk/decorators/llm_entrypoint.py,sha256
|
|
135
|
-
agenta/sdk/decorators/tracing.py,sha256=
|
|
134
|
+
agenta/sdk/decorators/llm_entrypoint.py,sha256=-oVl2sBH8tIjFD_6q6l0LmEPrPlfRT9Iy8KqEYxJvwk,28099
|
|
135
|
+
agenta/sdk/decorators/tracing.py,sha256=jjHD6VY5YSSHLfC3C2Xl7-6psBq8ycczMB0kj1rYwl4,3749
|
|
136
136
|
agenta/sdk/router.py,sha256=0sbajvn5C7t18anH6yNo7-oYxldHnYfwcbmQnIXBePw,269
|
|
137
137
|
agenta/sdk/tracing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
138
|
-
agenta/sdk/tracing/callbacks.py,sha256=
|
|
138
|
+
agenta/sdk/tracing/callbacks.py,sha256=xWP3RRtmj3ogXeqYI6zdj6gF5QGu70UlQ17WNwdXIx8,8063
|
|
139
139
|
agenta/sdk/tracing/context_manager.py,sha256=HskDaiORoOhjeN375gm05wYnieQzh5UnoIsnSAHkAyc,252
|
|
140
|
-
agenta/sdk/tracing/llm_tracing.py,sha256=
|
|
140
|
+
agenta/sdk/tracing/llm_tracing.py,sha256=A7_-Xx3Rioh_nfT7OjZvDPbKUvxEqruKhYRfdGwyo4w,17312
|
|
141
141
|
agenta/sdk/tracing/logger.py,sha256=GfH7V-jBHcn7h5dbdrnkDMe_ml3wkXFBeoQiqR4KVRc,474
|
|
142
142
|
agenta/sdk/tracing/tasks_manager.py,sha256=FBSFOWIKBycyA4ShB2ZVMzrzYQ8pWGWWBClFX8nlZFA,3726
|
|
143
|
-
agenta/sdk/tracing/tracing_context.py,sha256=
|
|
143
|
+
agenta/sdk/tracing/tracing_context.py,sha256=nt3ewa-TK9BRJviGIZYazsAQUiG4daWxjtsbjeaDprs,789
|
|
144
144
|
agenta/sdk/types.py,sha256=1rVy8ob-rTOrIFcSSseXrt0JQtqqhlJfVgVxCB2ErCk,5754
|
|
145
145
|
agenta/sdk/utils/debug.py,sha256=QyuPsSoN0425UD13x_msPxSF_VT6YwHiQunZUibI-jg,2149
|
|
146
146
|
agenta/sdk/utils/globals.py,sha256=JmhJcCOSbwvjQ6GDyUc2_SYR27DZk7YcrRH80ktHHOM,435
|
|
@@ -161,7 +161,7 @@ agenta/templates/simple_prompt/app.py,sha256=kODgF6lhzsaJPdgL5b21bUki6jkvqjWZzWR
|
|
|
161
161
|
agenta/templates/simple_prompt/env.example,sha256=g9AE5bYcGPpxawXMJ96gh8oenEPCHTabsiOnfQo3c5k,70
|
|
162
162
|
agenta/templates/simple_prompt/requirements.txt,sha256=ywRglRy7pPkw8bljmMEJJ4aOOQKrt9FGKULZ-DGkoBU,23
|
|
163
163
|
agenta/templates/simple_prompt/template.toml,sha256=DQBtRrF4GU8LBEXOZ-GGuINXMQDKGTEG5y37tnvIUIE,60
|
|
164
|
-
agenta-0.20.
|
|
165
|
-
agenta-0.20.
|
|
166
|
-
agenta-0.20.
|
|
167
|
-
agenta-0.20.
|
|
164
|
+
agenta-0.20.0a3.dist-info/METADATA,sha256=ejs-P0QRRYTn33Pukab6fxUj8olSqlXVYy0kdsBsTRk,26462
|
|
165
|
+
agenta-0.20.0a3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
166
|
+
agenta-0.20.0a3.dist-info/entry_points.txt,sha256=PDiu8_8AsL7ibU9v4iNoOKR1S7F2rdxjlEprjM9QOgo,46
|
|
167
|
+
agenta-0.20.0a3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|