agenta 0.27.0a9__py3-none-any.whl → 0.27.0a13__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 +21 -3
- agenta/client/backend/__init__.py +14 -0
- agenta/client/backend/apps/client.py +28 -20
- agenta/client/backend/client.py +25 -2
- agenta/client/backend/containers/client.py +5 -1
- agenta/client/backend/core/__init__.py +2 -1
- agenta/client/backend/core/client_wrapper.py +6 -6
- agenta/client/backend/core/file.py +33 -11
- agenta/client/backend/core/http_client.py +24 -18
- agenta/client/backend/core/pydantic_utilities.py +144 -29
- agenta/client/backend/core/request_options.py +3 -0
- agenta/client/backend/core/serialization.py +139 -42
- agenta/client/backend/evaluations/client.py +7 -2
- agenta/client/backend/evaluators/client.py +349 -1
- agenta/client/backend/observability/client.py +11 -2
- agenta/client/backend/testsets/client.py +10 -10
- agenta/client/backend/types/__init__.py +14 -0
- agenta/client/backend/types/app.py +1 -0
- agenta/client/backend/types/app_variant_response.py +3 -1
- agenta/client/backend/types/config_dto.py +32 -0
- agenta/client/backend/types/config_response_model.py +32 -0
- agenta/client/backend/types/create_span.py +3 -2
- agenta/client/backend/types/environment_output.py +1 -0
- agenta/client/backend/types/environment_output_extended.py +1 -0
- agenta/client/backend/types/evaluation.py +1 -2
- agenta/client/backend/types/evaluator.py +2 -0
- agenta/client/backend/types/evaluator_config.py +1 -0
- agenta/client/backend/types/evaluator_mapping_output_interface.py +21 -0
- agenta/client/backend/types/evaluator_output_interface.py +21 -0
- agenta/client/backend/types/human_evaluation.py +1 -2
- agenta/client/backend/types/lifecycle_dto.py +24 -0
- agenta/client/backend/types/llm_tokens.py +2 -2
- agenta/client/backend/types/reference_dto.py +23 -0
- agenta/client/backend/types/reference_request_model.py +23 -0
- agenta/client/backend/types/span.py +1 -0
- agenta/client/backend/types/span_detail.py +7 -1
- agenta/client/backend/types/test_set_output_response.py +5 -2
- agenta/client/backend/types/trace_detail.py +7 -1
- agenta/client/backend/types/with_pagination.py +4 -2
- agenta/client/backend/variants/client.py +1565 -272
- agenta/docker/docker-assets/Dockerfile.cloud.template +1 -1
- agenta/sdk/__init__.py +19 -5
- agenta/sdk/agenta_init.py +21 -7
- agenta/sdk/context/routing.py +6 -5
- agenta/sdk/decorators/routing.py +16 -5
- agenta/sdk/decorators/tracing.py +16 -9
- agenta/sdk/litellm/litellm.py +47 -36
- agenta/sdk/managers/__init__.py +6 -0
- agenta/sdk/managers/config.py +318 -0
- agenta/sdk/managers/deployment.py +45 -0
- agenta/sdk/managers/shared.py +639 -0
- agenta/sdk/managers/variant.py +182 -0
- agenta/sdk/tracing/exporters.py +0 -1
- agenta/sdk/tracing/inline.py +46 -1
- agenta/sdk/tracing/processors.py +0 -1
- agenta/sdk/types.py +47 -2
- agenta/sdk/utils/exceptions.py +31 -1
- {agenta-0.27.0a9.dist-info → agenta-0.27.0a13.dist-info}/METADATA +1 -1
- {agenta-0.27.0a9.dist-info → agenta-0.27.0a13.dist-info}/RECORD +61 -50
- agenta/sdk/config_manager.py +0 -205
- {agenta-0.27.0a9.dist-info → agenta-0.27.0a13.dist-info}/WHEEL +0 -0
- {agenta-0.27.0a9.dist-info → agenta-0.27.0a13.dist-info}/entry_points.txt +0 -0
agenta/sdk/__init__.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from .utils.preinit import PreInitObject # always the first import!
|
|
4
|
+
|
|
5
|
+
import agenta.client.backend.types as client_types # pylint: disable=wrong-import-order
|
|
6
|
+
|
|
4
7
|
from .types import (
|
|
5
8
|
DictInput,
|
|
6
9
|
MultipleChoice,
|
|
@@ -21,12 +24,19 @@ from .tracing.conventions import Reference
|
|
|
21
24
|
from .decorators.routing import entrypoint, app, route
|
|
22
25
|
from .agenta_init import Config, AgentaSingleton, init as _init
|
|
23
26
|
from .utils.costs import calculate_token_usage
|
|
24
|
-
from .
|
|
27
|
+
from .managers.config import ConfigManager
|
|
28
|
+
from .managers.variant import VariantManager
|
|
29
|
+
from .managers.deployment import DeploymentManager
|
|
25
30
|
|
|
26
31
|
config = PreInitObject("agenta.config", Config)
|
|
27
32
|
DEFAULT_AGENTA_SINGLETON_INSTANCE = AgentaSingleton()
|
|
28
|
-
tracing = DEFAULT_AGENTA_SINGLETON_INSTANCE.tracing # type: ignore
|
|
29
33
|
|
|
34
|
+
types = client_types
|
|
35
|
+
|
|
36
|
+
api = None
|
|
37
|
+
async_api = None
|
|
38
|
+
|
|
39
|
+
tracing = DEFAULT_AGENTA_SINGLETON_INSTANCE.tracing # type: ignore
|
|
30
40
|
tracer = get_tracer(tracing)
|
|
31
41
|
|
|
32
42
|
|
|
@@ -36,14 +46,18 @@ def init(
|
|
|
36
46
|
api_key: Optional[str] = None,
|
|
37
47
|
config_fname: Optional[str] = None,
|
|
38
48
|
):
|
|
39
|
-
global tracing
|
|
40
|
-
global tracer
|
|
49
|
+
global api, async_api, tracing, tracer
|
|
41
50
|
|
|
42
51
|
_init(
|
|
43
52
|
host=host,
|
|
44
|
-
app_id=app_id,
|
|
45
53
|
api_key=api_key,
|
|
46
54
|
config_fname=config_fname,
|
|
55
|
+
# DEPRECATING
|
|
56
|
+
app_id=app_id,
|
|
47
57
|
)
|
|
48
58
|
|
|
59
|
+
api = DEFAULT_AGENTA_SINGLETON_INSTANCE.api # type: ignore
|
|
60
|
+
async_api = DEFAULT_AGENTA_SINGLETON_INSTANCE.async_api # type: ignore
|
|
61
|
+
|
|
62
|
+
tracing = DEFAULT_AGENTA_SINGLETON_INSTANCE.tracing # type: ignore
|
|
49
63
|
tracer = get_tracer(tracing)
|
agenta/sdk/agenta_init.py
CHANGED
|
@@ -6,7 +6,7 @@ from importlib.metadata import version
|
|
|
6
6
|
|
|
7
7
|
from agenta.sdk.utils.logging import log
|
|
8
8
|
from agenta.sdk.utils.globals import set_global
|
|
9
|
-
from agenta.client.backend.client import AgentaApi
|
|
9
|
+
from agenta.client.backend.client import AgentaApi, AsyncAgentaApi
|
|
10
10
|
from agenta.sdk.tracing import Tracing
|
|
11
11
|
from agenta.client.exceptions import APIRequestError
|
|
12
12
|
|
|
@@ -22,6 +22,9 @@ class AgentaSingleton:
|
|
|
22
22
|
config = None
|
|
23
23
|
tracing = None
|
|
24
24
|
|
|
25
|
+
api = None
|
|
26
|
+
async_api = None
|
|
27
|
+
|
|
25
28
|
def __new__(cls):
|
|
26
29
|
if not cls._instance:
|
|
27
30
|
cls._instance = super(AgentaSingleton, cls).__new__(cls)
|
|
@@ -33,14 +36,11 @@ class AgentaSingleton:
|
|
|
33
36
|
host: Optional[str] = None,
|
|
34
37
|
api_key: Optional[str] = None,
|
|
35
38
|
config_fname: Optional[str] = None,
|
|
36
|
-
#
|
|
39
|
+
# DEPRECATING
|
|
37
40
|
app_id: Optional[str] = None,
|
|
38
41
|
) -> None:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
log.info(f"---------------------------")
|
|
42
|
-
|
|
43
|
-
"""Main function to initialize the singleton.
|
|
42
|
+
"""
|
|
43
|
+
Main function to initialize the singleton.
|
|
44
44
|
|
|
45
45
|
Initializes the singleton with the given `app_id`, `host`, and `api_key`. The order of precedence for these variables is:
|
|
46
46
|
1. Explicit argument provided in the function call.
|
|
@@ -62,6 +62,10 @@ class AgentaSingleton:
|
|
|
62
62
|
ValueError: If `app_id` is not specified either as an argument, in the config file, or in the environment variables.
|
|
63
63
|
"""
|
|
64
64
|
|
|
65
|
+
log.info("---------------------------")
|
|
66
|
+
log.info("Agenta SDK - using version: %s", version("agenta"))
|
|
67
|
+
log.info("---------------------------")
|
|
68
|
+
|
|
65
69
|
config = {}
|
|
66
70
|
if config_fname:
|
|
67
71
|
config = toml.load(config_fname)
|
|
@@ -97,6 +101,16 @@ class AgentaSingleton:
|
|
|
97
101
|
app_id=self.app_id,
|
|
98
102
|
)
|
|
99
103
|
|
|
104
|
+
self.api = AgentaApi(
|
|
105
|
+
base_url=self.host + "/api",
|
|
106
|
+
api_key=api_key if api_key else "",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
self.async_api = AsyncAgentaApi(
|
|
110
|
+
base_url=self.host + "/api",
|
|
111
|
+
api_key=api_key if api_key else "",
|
|
112
|
+
)
|
|
113
|
+
|
|
100
114
|
self.base_id = os.environ.get("AGENTA_BASE_ID")
|
|
101
115
|
|
|
102
116
|
self.config = Config(
|
agenta/sdk/context/routing.py
CHANGED
|
@@ -7,16 +7,17 @@ routing_context = ContextVar("routing_context", default={})
|
|
|
7
7
|
|
|
8
8
|
@contextmanager
|
|
9
9
|
def routing_context_manager(
|
|
10
|
+
*,
|
|
10
11
|
config: Optional[Dict[str, Any]] = None,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
application: Optional[Dict[str, Any]] = None,
|
|
13
|
+
variant: Optional[Dict[str, Any]] = None,
|
|
14
|
+
environment: Optional[Dict[str, Any]] = None,
|
|
14
15
|
):
|
|
15
16
|
context = {
|
|
16
17
|
"config": config,
|
|
17
|
-
"
|
|
18
|
-
"version": version,
|
|
18
|
+
"application": application,
|
|
19
19
|
"variant": variant,
|
|
20
|
+
"environment": environment,
|
|
20
21
|
}
|
|
21
22
|
token = routing_context.set(context)
|
|
22
23
|
try:
|
agenta/sdk/decorators/routing.py
CHANGED
|
@@ -9,6 +9,7 @@ from asyncio import sleep, get_event_loop
|
|
|
9
9
|
from traceback import format_exc, format_exception
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
from tempfile import NamedTemporaryFile
|
|
12
|
+
from os import environ
|
|
12
13
|
|
|
13
14
|
from fastapi.middleware.cors import CORSMiddleware
|
|
14
15
|
from fastapi import Body, FastAPI, UploadFile, HTTPException
|
|
@@ -152,7 +153,6 @@ class entrypoint:
|
|
|
152
153
|
|
|
153
154
|
with routing_context_manager(
|
|
154
155
|
config=api_config_params,
|
|
155
|
-
environment="playground",
|
|
156
156
|
):
|
|
157
157
|
entrypoint_result = await self.execute_function(
|
|
158
158
|
func,
|
|
@@ -209,7 +209,9 @@ class entrypoint:
|
|
|
209
209
|
@wraps(func)
|
|
210
210
|
async def wrapper_deployed(*args, **kwargs) -> Any:
|
|
211
211
|
func_params = {
|
|
212
|
-
k: v
|
|
212
|
+
k: v
|
|
213
|
+
for k, v in kwargs.items()
|
|
214
|
+
if k not in ["config", "environment", "app"]
|
|
213
215
|
}
|
|
214
216
|
if not config_schema:
|
|
215
217
|
if "environment" in kwargs and kwargs["environment"] is not None:
|
|
@@ -219,10 +221,19 @@ class entrypoint:
|
|
|
219
221
|
else:
|
|
220
222
|
ag.config.pull(config_name="default")
|
|
221
223
|
|
|
224
|
+
app_id = environ.get("AGENTA_APP_ID")
|
|
225
|
+
|
|
222
226
|
with routing_context_manager(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
227
|
+
application={
|
|
228
|
+
"id": app_id,
|
|
229
|
+
"slug": kwargs["app"],
|
|
230
|
+
},
|
|
231
|
+
variant={
|
|
232
|
+
"slug": kwargs.get("config"),
|
|
233
|
+
},
|
|
234
|
+
environment={
|
|
235
|
+
"slug": kwargs.get("environment"),
|
|
236
|
+
},
|
|
226
237
|
):
|
|
227
238
|
entrypoint_result = await self.execute_function(
|
|
228
239
|
func,
|
agenta/sdk/decorators/tracing.py
CHANGED
|
@@ -10,12 +10,12 @@ from agenta.sdk.tracing.conventions import parse_span_kind
|
|
|
10
10
|
import agenta as ag
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class instrument:
|
|
13
|
+
class instrument: # pylint: disable=invalid-name
|
|
14
14
|
DEFAULT_KEY = "__default__"
|
|
15
15
|
|
|
16
16
|
def __init__(
|
|
17
17
|
self,
|
|
18
|
-
type: str = "task",
|
|
18
|
+
type: str = "task", # pylint: disable=redefined-builtin
|
|
19
19
|
config: Optional[Dict[str, Any]] = None,
|
|
20
20
|
ignore_inputs: Optional[bool] = None,
|
|
21
21
|
ignore_outputs: Optional[bool] = None,
|
|
@@ -196,12 +196,16 @@ class instrument:
|
|
|
196
196
|
ignore: Union[List[str], bool] = False,
|
|
197
197
|
) -> Dict[str, Any]:
|
|
198
198
|
"""
|
|
199
|
-
Redact user-defined sensitive information
|
|
199
|
+
Redact user-defined sensitive information
|
|
200
|
+
from inputs and outputs as defined by the ignore list or boolean flag.
|
|
200
201
|
|
|
201
202
|
Example:
|
|
202
|
-
- ignore = ["password"] -> {"username": "admin", "password": "********"}
|
|
203
|
-
|
|
204
|
-
- ignore =
|
|
203
|
+
- ignore = ["password"] -> {"username": "admin", "password": "********"}
|
|
204
|
+
-> {"username": "admin"}
|
|
205
|
+
- ignore = True -> {"username": "admin", "password": "********"}
|
|
206
|
+
-> {}
|
|
207
|
+
- ignore = False -> {"username": "admin", "password": "********"}
|
|
208
|
+
-> {"username": "admin", "password": "********"}
|
|
205
209
|
"""
|
|
206
210
|
io = {
|
|
207
211
|
key: value
|
|
@@ -226,9 +230,12 @@ class instrument:
|
|
|
226
230
|
Patch the result to ensure that it is a dictionary, with a default key when necessary.
|
|
227
231
|
|
|
228
232
|
Example:
|
|
229
|
-
- result = "Hello, World!"
|
|
230
|
-
|
|
231
|
-
- result = {"message": "Hello, World!"
|
|
233
|
+
- result = "Hello, World!"
|
|
234
|
+
-> {"__default__": "Hello, World!"}
|
|
235
|
+
- result = {"message": "Hello, World!", "cost": 0.0, "usage": {}}
|
|
236
|
+
-> {"__default__": "Hello, World!"}
|
|
237
|
+
- result = {"message": "Hello, World!"}
|
|
238
|
+
-> {"message": "Hello, World!"}
|
|
232
239
|
"""
|
|
233
240
|
outputs = (
|
|
234
241
|
{instrument.DEFAULT_KEY: result}
|
agenta/sdk/litellm/litellm.py
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import agenta as ag
|
|
2
|
-
|
|
3
1
|
from opentelemetry.trace import SpanKind
|
|
4
2
|
|
|
3
|
+
import agenta as ag
|
|
4
|
+
|
|
5
5
|
from agenta.sdk.tracing.spans import CustomSpan
|
|
6
|
-
from agenta.sdk.utils.exceptions import suppress
|
|
6
|
+
from agenta.sdk.utils.exceptions import suppress # TODO: use it !
|
|
7
7
|
from agenta.sdk.utils.logging import log
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def litellm_handler():
|
|
11
11
|
try:
|
|
12
|
-
from litellm.
|
|
13
|
-
from litellm.integrations.custom_logger import (
|
|
12
|
+
from litellm.integrations.custom_logger import ( # pylint: disable=import-outside-toplevel
|
|
14
13
|
CustomLogger as LitellmCustomLogger,
|
|
15
14
|
)
|
|
16
15
|
except ImportError as exc:
|
|
@@ -18,18 +17,23 @@ def litellm_handler():
|
|
|
18
17
|
"The litellm SDK is not installed. Please install it using `pip install litellm`."
|
|
19
18
|
) from exc
|
|
20
19
|
except Exception as exc:
|
|
21
|
-
raise Exception(
|
|
22
|
-
"Unexpected error occurred when importing litellm: {}"
|
|
20
|
+
raise Exception( # pylint: disable=broad-exception-raised
|
|
21
|
+
f"Unexpected error occurred when importing litellm: {exc}"
|
|
23
22
|
) from exc
|
|
24
23
|
|
|
25
24
|
class LitellmHandler(LitellmCustomLogger):
|
|
26
|
-
"""
|
|
25
|
+
"""
|
|
26
|
+
This handler is responsible for instrumenting certain events,
|
|
27
|
+
when using litellm to call LLMs.
|
|
27
28
|
|
|
28
29
|
Args:
|
|
29
|
-
LitellmCustomLogger (object): custom logger that allows us
|
|
30
|
+
LitellmCustomLogger (object): custom logger that allows us
|
|
31
|
+
to override the events to capture.
|
|
30
32
|
"""
|
|
31
33
|
|
|
32
34
|
def __init__(self):
|
|
35
|
+
super().__init__()
|
|
36
|
+
|
|
33
37
|
self.span = None
|
|
34
38
|
|
|
35
39
|
def log_pre_api_call(
|
|
@@ -38,7 +42,7 @@ def litellm_handler():
|
|
|
38
42
|
messages,
|
|
39
43
|
kwargs,
|
|
40
44
|
):
|
|
41
|
-
type = (
|
|
45
|
+
type = ( # pylint: disable=redefined-builtin
|
|
42
46
|
"chat"
|
|
43
47
|
if kwargs.get("call_type") in ["completion", "acompletion"]
|
|
44
48
|
else "embedding"
|
|
@@ -59,10 +63,8 @@ def litellm_handler():
|
|
|
59
63
|
log.error("LiteLLM callback error: span not found.")
|
|
60
64
|
return
|
|
61
65
|
|
|
62
|
-
log.info(f"log_pre_api_call({hex(self.span.context.span_id)[2:]})")
|
|
63
|
-
|
|
64
66
|
self.span.set_attributes(
|
|
65
|
-
attributes={"inputs": {"
|
|
67
|
+
attributes={"inputs": {"prompt": kwargs["messages"]}},
|
|
66
68
|
namespace="data",
|
|
67
69
|
)
|
|
68
70
|
|
|
@@ -87,12 +89,14 @@ def litellm_handler():
|
|
|
87
89
|
log.error("LiteLLM callback error: span not found.")
|
|
88
90
|
return
|
|
89
91
|
|
|
90
|
-
|
|
92
|
+
result = kwargs.get("complete_streaming_response")
|
|
93
|
+
|
|
94
|
+
outputs = (
|
|
95
|
+
{"__default__": result} if not isinstance(result, dict) else result
|
|
96
|
+
)
|
|
91
97
|
|
|
92
98
|
self.span.set_attributes(
|
|
93
|
-
attributes={
|
|
94
|
-
"output": {"__default__": kwargs.get("complete_streaming_response")}
|
|
95
|
-
},
|
|
99
|
+
attributes={"outputs": outputs},
|
|
96
100
|
namespace="data",
|
|
97
101
|
)
|
|
98
102
|
|
|
@@ -127,14 +131,20 @@ def litellm_handler():
|
|
|
127
131
|
log.error("LiteLLM callback error: span not found.")
|
|
128
132
|
return
|
|
129
133
|
|
|
130
|
-
|
|
134
|
+
try:
|
|
135
|
+
result = []
|
|
136
|
+
for choice in response_obj.choices:
|
|
137
|
+
message = choice.message.__dict__
|
|
138
|
+
result.append(message)
|
|
131
139
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
140
|
+
outputs = {"completion": result}
|
|
141
|
+
self.span.set_attributes(
|
|
142
|
+
attributes={"outputs": outputs},
|
|
143
|
+
namespace="data",
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
except Exception as e:
|
|
147
|
+
pass
|
|
138
148
|
|
|
139
149
|
self.span.set_attributes(
|
|
140
150
|
attributes={"total": kwargs.get("response_cost")},
|
|
@@ -167,8 +177,6 @@ def litellm_handler():
|
|
|
167
177
|
log.error("LiteLLM callback error: span not found.")
|
|
168
178
|
return
|
|
169
179
|
|
|
170
|
-
# log.info(f"log_failure({hex(self.span.context.span_id)[2:]})")
|
|
171
|
-
|
|
172
180
|
self.span.record_exception(kwargs["exception"])
|
|
173
181
|
|
|
174
182
|
self.span.set_status(status="ERROR")
|
|
@@ -186,12 +194,14 @@ def litellm_handler():
|
|
|
186
194
|
log.error("LiteLLM callback error: span not found.")
|
|
187
195
|
return
|
|
188
196
|
|
|
189
|
-
|
|
197
|
+
result = kwargs.get("complete_streaming_response")
|
|
198
|
+
|
|
199
|
+
outputs = (
|
|
200
|
+
{"__default__": result} if not isinstance(result, dict) else result
|
|
201
|
+
)
|
|
190
202
|
|
|
191
203
|
self.span.set_attributes(
|
|
192
|
-
attributes={
|
|
193
|
-
"output": {"__default__": kwargs.get("complete_streaming_response")}
|
|
194
|
-
},
|
|
204
|
+
attributes={"outputs": outputs},
|
|
195
205
|
namespace="data",
|
|
196
206
|
)
|
|
197
207
|
|
|
@@ -226,12 +236,15 @@ def litellm_handler():
|
|
|
226
236
|
log.error("LiteLLM callback error: span not found.")
|
|
227
237
|
return
|
|
228
238
|
|
|
229
|
-
|
|
239
|
+
# result = kwargs.get("complete_streaming_response")
|
|
240
|
+
result = response_obj.choices[0].message.content
|
|
241
|
+
|
|
242
|
+
outputs = (
|
|
243
|
+
{"__default__": result} if not isinstance(result, dict) else result
|
|
244
|
+
)
|
|
230
245
|
|
|
231
246
|
self.span.set_attributes(
|
|
232
|
-
attributes={
|
|
233
|
-
"output": {"__default__": kwargs.get("complete_streaming_response")}
|
|
234
|
-
},
|
|
247
|
+
attributes={"outputs": outputs},
|
|
235
248
|
namespace="data",
|
|
236
249
|
)
|
|
237
250
|
|
|
@@ -266,8 +279,6 @@ def litellm_handler():
|
|
|
266
279
|
log.error("LiteLLM callback error: span not found.")
|
|
267
280
|
return
|
|
268
281
|
|
|
269
|
-
# log.info(f"async_log_failure({hex(self.span.context.span_id)[2:]})")
|
|
270
|
-
|
|
271
282
|
self.span.record_exception(kwargs["exception"])
|
|
272
283
|
|
|
273
284
|
self.span.set_status(status="ERROR")
|