oracle-ads 2.12.9__py3-none-any.whl → 2.12.10__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.
- ads/aqua/__init__.py +4 -3
- ads/aqua/app.py +28 -16
- ads/aqua/client/__init__.py +3 -0
- ads/aqua/client/client.py +799 -0
- ads/aqua/common/enums.py +3 -0
- ads/aqua/common/utils.py +62 -2
- ads/aqua/data.py +2 -19
- ads/aqua/evaluation/evaluation.py +20 -12
- ads/aqua/extension/aqua_ws_msg_handler.py +14 -7
- ads/aqua/extension/base_handler.py +12 -9
- ads/aqua/extension/finetune_handler.py +8 -14
- ads/aqua/extension/model_handler.py +24 -2
- ads/aqua/finetuning/constants.py +5 -2
- ads/aqua/finetuning/entities.py +67 -17
- ads/aqua/finetuning/finetuning.py +69 -54
- ads/aqua/model/entities.py +3 -1
- ads/aqua/model/model.py +196 -98
- ads/aqua/modeldeployment/deployment.py +22 -10
- ads/cli.py +16 -8
- ads/common/auth.py +9 -9
- ads/llm/autogen/__init__.py +2 -0
- ads/llm/autogen/constants.py +15 -0
- ads/llm/autogen/reports/__init__.py +2 -0
- ads/llm/autogen/reports/base.py +67 -0
- ads/llm/autogen/reports/data.py +103 -0
- ads/llm/autogen/reports/session.py +526 -0
- ads/llm/autogen/reports/templates/chat_box.html +13 -0
- ads/llm/autogen/reports/templates/chat_box_lt.html +5 -0
- ads/llm/autogen/reports/templates/chat_box_rt.html +6 -0
- ads/llm/autogen/reports/utils.py +56 -0
- ads/llm/autogen/v02/__init__.py +4 -0
- ads/llm/autogen/{client_v02.py → v02/client.py} +23 -10
- ads/llm/autogen/v02/log_handlers/__init__.py +2 -0
- ads/llm/autogen/v02/log_handlers/oci_file_handler.py +83 -0
- ads/llm/autogen/v02/loggers/__init__.py +6 -0
- ads/llm/autogen/v02/loggers/metric_logger.py +320 -0
- ads/llm/autogen/v02/loggers/session_logger.py +580 -0
- ads/llm/autogen/v02/loggers/utils.py +86 -0
- ads/llm/autogen/v02/runtime_logging.py +163 -0
- ads/llm/langchain/plugins/chat_models/oci_data_science.py +12 -11
- ads/model/__init__.py +11 -13
- ads/model/artifact.py +47 -8
- ads/model/extractor/embedding_onnx_extractor.py +80 -0
- ads/model/framework/embedding_onnx_model.py +438 -0
- ads/model/generic_model.py +26 -24
- ads/model/model_metadata.py +8 -7
- ads/opctl/config/merger.py +13 -14
- ads/opctl/operator/common/operator_config.py +4 -4
- ads/opctl/operator/lowcode/common/transformations.py +50 -8
- ads/opctl/operator/lowcode/common/utils.py +22 -6
- ads/opctl/operator/lowcode/forecast/__main__.py +10 -0
- ads/opctl/operator/lowcode/forecast/const.py +2 -0
- ads/opctl/operator/lowcode/forecast/model/arima.py +19 -13
- ads/opctl/operator/lowcode/forecast/model/automlx.py +129 -36
- ads/opctl/operator/lowcode/forecast/model/autots.py +1 -0
- ads/opctl/operator/lowcode/forecast/model/base_model.py +61 -14
- ads/opctl/operator/lowcode/forecast/model/forecast_datasets.py +1 -1
- ads/opctl/operator/lowcode/forecast/model/neuralprophet.py +10 -3
- ads/opctl/operator/lowcode/forecast/model/prophet.py +25 -18
- ads/opctl/operator/lowcode/forecast/operator_config.py +31 -0
- ads/opctl/operator/lowcode/forecast/schema.yaml +76 -0
- ads/opctl/operator/lowcode/forecast/utils.py +4 -3
- ads/opctl/operator/lowcode/forecast/whatifserve/__init__.py +7 -0
- ads/opctl/operator/lowcode/forecast/whatifserve/deployment_manager.py +233 -0
- ads/opctl/operator/lowcode/forecast/whatifserve/score.py +238 -0
- ads/telemetry/base.py +18 -11
- ads/telemetry/client.py +33 -13
- ads/templates/schemas/openapi.json +1740 -0
- ads/templates/score_embedding_onnx.jinja2 +202 -0
- {oracle_ads-2.12.9.dist-info → oracle_ads-2.12.10.dist-info}/METADATA +9 -8
- {oracle_ads-2.12.9.dist-info → oracle_ads-2.12.10.dist-info}/RECORD +74 -48
- {oracle_ads-2.12.9.dist-info → oracle_ads-2.12.10.dist-info}/LICENSE.txt +0 -0
- {oracle_ads-2.12.9.dist-info → oracle_ads-2.12.10.dist-info}/WHEEL +0 -0
- {oracle_ads-2.12.9.dist-info → oracle_ads-2.12.10.dist-info}/entry_points.txt +0 -0
@@ -1,8 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
# Copyright (c) 2024 Oracle and/or its affiliates.
|
2
|
+
# Copyright (c) 2024, 2025 Oracle and/or its affiliates.
|
3
3
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
4
4
|
|
5
|
-
import logging
|
6
5
|
import shlex
|
7
6
|
from typing import Dict, List, Optional, Union
|
8
7
|
|
@@ -271,7 +270,7 @@ class AquaDeploymentApp(AquaApp):
|
|
271
270
|
f"field. Either re-register the model with custom container URI, or set container_image_uri "
|
272
271
|
f"parameter when creating this deployment."
|
273
272
|
) from err
|
274
|
-
|
273
|
+
logger.info(
|
275
274
|
f"Aqua Image used for deploying {aqua_model.id} : {container_image_uri}"
|
276
275
|
)
|
277
276
|
|
@@ -282,14 +281,14 @@ class AquaDeploymentApp(AquaApp):
|
|
282
281
|
default_cmd_var = shlex.split(cmd_var_string)
|
283
282
|
if default_cmd_var:
|
284
283
|
cmd_var = validate_cmd_var(default_cmd_var, cmd_var)
|
285
|
-
|
284
|
+
logger.info(f"CMD used for deploying {aqua_model.id} :{cmd_var}")
|
286
285
|
except ValueError:
|
287
|
-
|
286
|
+
logger.debug(
|
288
287
|
f"CMD will be ignored for this deployment as {AQUA_DEPLOYMENT_CONTAINER_CMD_VAR_METADATA_NAME} "
|
289
288
|
f"key is not available in the custom metadata field for this model."
|
290
289
|
)
|
291
290
|
except Exception as e:
|
292
|
-
|
291
|
+
logger.error(
|
293
292
|
f"There was an issue processing CMD arguments. Error: {str(e)}"
|
294
293
|
)
|
295
294
|
|
@@ -385,7 +384,7 @@ class AquaDeploymentApp(AquaApp):
|
|
385
384
|
if key not in env_var:
|
386
385
|
env_var.update(env)
|
387
386
|
|
388
|
-
|
387
|
+
logger.info(f"Env vars used for deploying {aqua_model.id} :{env_var}")
|
389
388
|
|
390
389
|
# Start model deployment
|
391
390
|
# configure model deployment infrastructure
|
@@ -440,10 +439,14 @@ class AquaDeploymentApp(AquaApp):
|
|
440
439
|
.with_runtime(container_runtime)
|
441
440
|
).deploy(wait_for_completion=False)
|
442
441
|
|
442
|
+
deployment_id = deployment.dsc_model_deployment.id
|
443
|
+
logger.info(
|
444
|
+
f"Aqua model deployment {deployment_id} created for model {aqua_model.id}."
|
445
|
+
)
|
443
446
|
model_type = (
|
444
447
|
AQUA_MODEL_TYPE_CUSTOM if is_fine_tuned_model else AQUA_MODEL_TYPE_SERVICE
|
445
448
|
)
|
446
|
-
|
449
|
+
|
447
450
|
# we arbitrarily choose last 8 characters of OCID to identify MD in telemetry
|
448
451
|
telemetry_kwargs = {"ocid": get_ocid_substring(deployment_id, key_len=8)}
|
449
452
|
|
@@ -539,6 +542,9 @@ class AquaDeploymentApp(AquaApp):
|
|
539
542
|
value=state,
|
540
543
|
)
|
541
544
|
|
545
|
+
logger.info(
|
546
|
+
f"Fetched {len(results)} model deployments from compartment_id={compartment_id}."
|
547
|
+
)
|
542
548
|
# tracks number of times deployment listing was called
|
543
549
|
self.telemetry.record_event_async(category="aqua/deployment", action="list")
|
544
550
|
|
@@ -546,18 +552,21 @@ class AquaDeploymentApp(AquaApp):
|
|
546
552
|
|
547
553
|
@telemetry(entry_point="plugin=deployment&action=delete", name="aqua")
|
548
554
|
def delete(self, model_deployment_id: str):
|
555
|
+
logger.info(f"Deleting model deployment {model_deployment_id}.")
|
549
556
|
return self.ds_client.delete_model_deployment(
|
550
557
|
model_deployment_id=model_deployment_id
|
551
558
|
).data
|
552
559
|
|
553
560
|
@telemetry(entry_point="plugin=deployment&action=deactivate", name="aqua")
|
554
561
|
def deactivate(self, model_deployment_id: str):
|
562
|
+
logger.info(f"Deactivating model deployment {model_deployment_id}.")
|
555
563
|
return self.ds_client.deactivate_model_deployment(
|
556
564
|
model_deployment_id=model_deployment_id
|
557
565
|
).data
|
558
566
|
|
559
567
|
@telemetry(entry_point="plugin=deployment&action=activate", name="aqua")
|
560
568
|
def activate(self, model_deployment_id: str):
|
569
|
+
logger.info(f"Activating model deployment {model_deployment_id}.")
|
561
570
|
return self.ds_client.activate_model_deployment(
|
562
571
|
model_deployment_id=model_deployment_id
|
563
572
|
).data
|
@@ -579,6 +588,8 @@ class AquaDeploymentApp(AquaApp):
|
|
579
588
|
AquaDeploymentDetail:
|
580
589
|
The instance of the Aqua model deployment details.
|
581
590
|
"""
|
591
|
+
logger.info(f"Fetching model deployment details for {model_deployment_id}.")
|
592
|
+
|
582
593
|
model_deployment = self.ds_client.get_model_deployment(
|
583
594
|
model_deployment_id=model_deployment_id, **kwargs
|
584
595
|
).data
|
@@ -594,7 +605,8 @@ class AquaDeploymentApp(AquaApp):
|
|
594
605
|
|
595
606
|
if not oci_aqua:
|
596
607
|
raise AquaRuntimeError(
|
597
|
-
f"Target deployment {model_deployment_id} is not Aqua deployment
|
608
|
+
f"Target deployment {model_deployment_id} is not Aqua deployment as it does not contain "
|
609
|
+
f"{Tags.AQUA_TAG} tag."
|
598
610
|
)
|
599
611
|
|
600
612
|
log_id = ""
|
@@ -652,7 +664,7 @@ class AquaDeploymentApp(AquaApp):
|
|
652
664
|
config = self.get_config(model_id, AQUA_MODEL_DEPLOYMENT_CONFIG)
|
653
665
|
if not config:
|
654
666
|
logger.debug(
|
655
|
-
f"Deployment config for custom model: {model_id} is not available."
|
667
|
+
f"Deployment config for custom model: {model_id} is not available. Use defaults."
|
656
668
|
)
|
657
669
|
return config
|
658
670
|
|
ads/cli.py
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
|
-
#
|
3
|
-
|
4
|
-
# Copyright (c) 2021, 2024 Oracle and/or its affiliates.
|
2
|
+
# Copyright (c) 2021, 2025 Oracle and/or its affiliates.
|
5
3
|
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
6
4
|
|
5
|
+
import json
|
6
|
+
import logging
|
7
7
|
import sys
|
8
8
|
import traceback
|
9
|
-
|
9
|
+
import uuid
|
10
10
|
|
11
11
|
import fire
|
12
|
+
from pydantic import BaseModel
|
12
13
|
|
13
14
|
from ads.common import logger
|
14
15
|
|
@@ -27,7 +28,7 @@ except Exception as ex:
|
|
27
28
|
)
|
28
29
|
logger.debug(ex)
|
29
30
|
logger.debug(traceback.format_exc())
|
30
|
-
exit()
|
31
|
+
sys.exit()
|
31
32
|
|
32
33
|
# https://packaging.python.org/en/latest/guides/single-sourcing-package-version/#single-sourcing-the-package-version
|
33
34
|
if sys.version_info >= (3, 8):
|
@@ -84,7 +85,13 @@ def serialize(data):
|
|
84
85
|
The string representation of each dataclass object.
|
85
86
|
"""
|
86
87
|
if isinstance(data, list):
|
87
|
-
|
88
|
+
for item in data:
|
89
|
+
if isinstance(item, BaseModel):
|
90
|
+
print(json.dumps(item.dict(), indent=4))
|
91
|
+
else:
|
92
|
+
print(str(item))
|
93
|
+
elif isinstance(data, BaseModel):
|
94
|
+
print(json.dumps(data.dict(), indent=4))
|
88
95
|
else:
|
89
96
|
print(str(data))
|
90
97
|
|
@@ -122,8 +129,9 @@ def exit_program(ex: Exception, logger: "logging.Logger") -> None:
|
|
122
129
|
... exit_program(e, logger)
|
123
130
|
"""
|
124
131
|
|
125
|
-
|
126
|
-
logger.
|
132
|
+
request_id = str(uuid.uuid4())
|
133
|
+
logger.debug(f"Error Request ID: {request_id}\nError: {traceback.format_exc()}")
|
134
|
+
logger.error(f"Error Request ID: {request_id}\n" f"Error: {str(ex)}")
|
127
135
|
|
128
136
|
exit_code = getattr(ex, "exit_code", 1)
|
129
137
|
logger.error(f"Exit code: {exit_code}")
|
ads/common/auth.py
CHANGED
@@ -424,7 +424,7 @@ def create_signer(
|
|
424
424
|
"signer": signer,
|
425
425
|
"client_kwargs": client_kwargs,
|
426
426
|
}
|
427
|
-
logger.
|
427
|
+
logger.debug(f"Using authentication signer type {type(signer)}.")
|
428
428
|
return signer_dict
|
429
429
|
else:
|
430
430
|
signer_args = dict(
|
@@ -492,7 +492,7 @@ def default_signer(client_kwargs: Optional[Dict] = None) -> Dict:
|
|
492
492
|
**(client_kwargs or {}),
|
493
493
|
},
|
494
494
|
}
|
495
|
-
logger.
|
495
|
+
logger.debug(f"Using authentication signer type {type(signer)}.")
|
496
496
|
return signer_dict
|
497
497
|
else:
|
498
498
|
signer_args = dict(
|
@@ -621,7 +621,7 @@ class APIKey(AuthSignerGenerator):
|
|
621
621
|
)
|
622
622
|
|
623
623
|
oci.config.validate_config(configuration)
|
624
|
-
logger.
|
624
|
+
logger.debug(f"Using 'api_key' authentication.")
|
625
625
|
return {
|
626
626
|
"config": configuration,
|
627
627
|
"signer": oci.signer.Signer(
|
@@ -684,7 +684,7 @@ class ResourcePrincipal(AuthSignerGenerator):
|
|
684
684
|
"signer": oci.auth.signers.get_resource_principals_signer(),
|
685
685
|
"client_kwargs": self.client_kwargs,
|
686
686
|
}
|
687
|
-
logger.
|
687
|
+
logger.debug(f"Using 'resource_principal' authentication.")
|
688
688
|
return signer_dict
|
689
689
|
|
690
690
|
@staticmethod
|
@@ -747,7 +747,7 @@ class InstancePrincipal(AuthSignerGenerator):
|
|
747
747
|
),
|
748
748
|
"client_kwargs": self.client_kwargs,
|
749
749
|
}
|
750
|
-
logger.
|
750
|
+
logger.debug(f"Using 'instance_principal' authentication.")
|
751
751
|
return signer_dict
|
752
752
|
|
753
753
|
|
@@ -814,7 +814,7 @@ class SecurityToken(AuthSignerGenerator):
|
|
814
814
|
oci.config.from_file(self.oci_config_location, self.oci_key_profile)
|
815
815
|
)
|
816
816
|
|
817
|
-
logger.
|
817
|
+
logger.debug(f"Using 'security_token' authentication.")
|
818
818
|
|
819
819
|
for parameter in self.SECURITY_TOKEN_REQUIRED:
|
820
820
|
if parameter not in configuration:
|
@@ -883,7 +883,7 @@ class SecurityToken(AuthSignerGenerator):
|
|
883
883
|
)
|
884
884
|
|
885
885
|
date_time = datetime.fromtimestamp(time_expired).strftime("%Y-%m-%d %H:%M:%S")
|
886
|
-
logger.
|
886
|
+
logger.debug(f"Session is valid until {date_time}.")
|
887
887
|
|
888
888
|
def _read_security_token_file(self, security_token_file: str) -> str:
|
889
889
|
"""Reads security token from file.
|
@@ -1020,10 +1020,10 @@ class OCIAuthContext:
|
|
1020
1020
|
"""
|
1021
1021
|
if self.profile:
|
1022
1022
|
ads.set_auth(auth=AuthType.API_KEY, profile=self.profile)
|
1023
|
-
logger.
|
1023
|
+
logger.debug(f"OCI profile set to {self.profile}")
|
1024
1024
|
else:
|
1025
1025
|
ads.set_auth(auth=AuthType.RESOURCE_PRINCIPAL)
|
1026
|
-
logger.
|
1026
|
+
logger.debug(f"OCI auth set to resource principal")
|
1027
1027
|
return self
|
1028
1028
|
|
1029
1029
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
ads/llm/autogen/__init__.py
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
2
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
3
|
+
|
4
|
+
|
5
|
+
class Events:
|
6
|
+
KEY = "event_name"
|
7
|
+
|
8
|
+
EXCEPTION = "exception"
|
9
|
+
LLM_CALL = "llm_call"
|
10
|
+
TOOL_CALL = "tool_call"
|
11
|
+
NEW_AGENT = "new_agent"
|
12
|
+
NEW_CLIENT = "new_client"
|
13
|
+
RECEIVED_MESSAGE = "received_message"
|
14
|
+
SESSION_START = "logging_session_start"
|
15
|
+
SESSION_STOP = "logging_session_stop"
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
2
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
3
|
+
import json
|
4
|
+
import logging
|
5
|
+
import os
|
6
|
+
|
7
|
+
from jinja2 import Environment, FileSystemLoader
|
8
|
+
|
9
|
+
logger = logging.getLogger(__name__)
|
10
|
+
|
11
|
+
|
12
|
+
class BaseReport:
|
13
|
+
"""Base class containing utilities for generating reports."""
|
14
|
+
|
15
|
+
@staticmethod
|
16
|
+
def format_json_string(s) -> str:
|
17
|
+
"""Formats the JSON string in markdown."""
|
18
|
+
return f"```json\n{json.dumps(json.loads(s), indent=2)}\n```"
|
19
|
+
|
20
|
+
@staticmethod
|
21
|
+
def _parse_date_time(datetime_string: str):
|
22
|
+
"""Parses a datetime string in the logs into date and time.
|
23
|
+
Keeps only the seconds in the time.
|
24
|
+
"""
|
25
|
+
date_str, time_str = datetime_string.split(" ", 1)
|
26
|
+
time_str = time_str.split(".", 1)[0]
|
27
|
+
return date_str, time_str
|
28
|
+
|
29
|
+
@staticmethod
|
30
|
+
def _preview_message(message: str, max_length=30) -> str:
|
31
|
+
"""Shows the beginning part of a string message."""
|
32
|
+
# Return the entire string if it is less than the max_length
|
33
|
+
if len(message) <= max_length:
|
34
|
+
return message
|
35
|
+
# Go backward until we find the first whitespace
|
36
|
+
idx = 30
|
37
|
+
while not message[idx].isspace() and idx > 0:
|
38
|
+
idx -= 1
|
39
|
+
# If we found a whitespace
|
40
|
+
if idx > 0:
|
41
|
+
return message[:idx] + "..."
|
42
|
+
# If we didn't find a whitespace
|
43
|
+
return message[:30] + "..."
|
44
|
+
|
45
|
+
@classmethod
|
46
|
+
def _render_template(cls, template_path, **kwargs) -> str:
|
47
|
+
"""Render Jinja template with kwargs."""
|
48
|
+
template_dir = os.path.join(os.path.dirname(__file__), "templates")
|
49
|
+
environment = Environment(
|
50
|
+
loader=FileSystemLoader(template_dir), autoescape=True
|
51
|
+
)
|
52
|
+
template = environment.get_template(template_path)
|
53
|
+
try:
|
54
|
+
html = template.render(**kwargs)
|
55
|
+
except Exception:
|
56
|
+
logger.error(
|
57
|
+
"Unable to render template %s with data:\n%s",
|
58
|
+
template_path,
|
59
|
+
str(kwargs),
|
60
|
+
)
|
61
|
+
return cls._render_template(
|
62
|
+
template_path=template_path,
|
63
|
+
sender=kwargs.get("sender", "N/A"),
|
64
|
+
content="TEMPLATE RENDER ERROR",
|
65
|
+
timestamp=kwargs.get("timestamp", ""),
|
66
|
+
)
|
67
|
+
return html
|
@@ -0,0 +1,103 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# Copyright (c) 2024 Oracle and/or its affiliates.
|
3
|
+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
4
|
+
"""Contains the data structure for logging and reporting."""
|
5
|
+
import copy
|
6
|
+
import json
|
7
|
+
from dataclasses import asdict, dataclass, field
|
8
|
+
from typing import Optional, Union
|
9
|
+
|
10
|
+
from ads.llm.autogen.constants import Events
|
11
|
+
|
12
|
+
|
13
|
+
@dataclass
|
14
|
+
class LogData:
|
15
|
+
"""Base class for the data field of LogRecord."""
|
16
|
+
|
17
|
+
def to_dict(self):
|
18
|
+
"""Convert the log data to dictionary."""
|
19
|
+
return asdict(self)
|
20
|
+
|
21
|
+
|
22
|
+
@dataclass
|
23
|
+
class LogRecord:
|
24
|
+
"""Represents a log record.
|
25
|
+
|
26
|
+
The `data` field is for pre-defined structured data, which should be an instance of LogData.
|
27
|
+
The `kwargs` field is for freeform key value pairs.
|
28
|
+
"""
|
29
|
+
|
30
|
+
session_id: str
|
31
|
+
thread_id: int
|
32
|
+
timestamp: str
|
33
|
+
event_name: str
|
34
|
+
source_id: Optional[int] = None
|
35
|
+
source_name: Optional[str] = None
|
36
|
+
# Structured data for specific type of logs
|
37
|
+
data: Optional[LogData] = None
|
38
|
+
# Freeform data
|
39
|
+
kwargs: dict = field(default_factory=dict)
|
40
|
+
|
41
|
+
def to_dict(self):
|
42
|
+
"""Convert the log record to dictionary."""
|
43
|
+
return asdict(self)
|
44
|
+
|
45
|
+
def to_string(self):
|
46
|
+
"""Serialize the log record to JSON string."""
|
47
|
+
return json.dumps(self.to_dict(), default=str)
|
48
|
+
|
49
|
+
@classmethod
|
50
|
+
def from_dict(cls, data: dict) -> "LogRecord":
|
51
|
+
"""Initializes a LogRecord object from dictionary."""
|
52
|
+
event_mapping = {
|
53
|
+
Events.NEW_AGENT: AgentData,
|
54
|
+
Events.TOOL_CALL: ToolCallData,
|
55
|
+
Events.LLM_CALL: LLMCompletionData,
|
56
|
+
}
|
57
|
+
if Events.KEY not in data:
|
58
|
+
raise KeyError("event_name not found in data.")
|
59
|
+
|
60
|
+
data = copy.deepcopy(data)
|
61
|
+
|
62
|
+
event_name = data["event_name"]
|
63
|
+
if event_name in event_mapping and data.get("data"):
|
64
|
+
data["data"] = event_mapping[event_name](**data.pop("data"))
|
65
|
+
|
66
|
+
return cls(**data)
|
67
|
+
|
68
|
+
|
69
|
+
@dataclass
|
70
|
+
class AgentData(LogData):
|
71
|
+
"""Represents agent log Data."""
|
72
|
+
|
73
|
+
agent_name: str
|
74
|
+
agent_class: str
|
75
|
+
agent_module: Optional[str] = None
|
76
|
+
is_manager: Optional[bool] = None
|
77
|
+
|
78
|
+
|
79
|
+
@dataclass
|
80
|
+
class LLMCompletionData(LogData):
|
81
|
+
"""Represents LLM completion log data."""
|
82
|
+
|
83
|
+
invocation_id: str
|
84
|
+
request: dict
|
85
|
+
response: dict
|
86
|
+
start_time: str
|
87
|
+
end_time: str
|
88
|
+
cost: Optional[float] = None
|
89
|
+
is_cached: Optional[bool] = None
|
90
|
+
|
91
|
+
|
92
|
+
@dataclass
|
93
|
+
class ToolCallData(LogData):
|
94
|
+
"""Represents tool call log data."""
|
95
|
+
|
96
|
+
tool_name: str
|
97
|
+
start_time: str
|
98
|
+
end_time: str
|
99
|
+
agent_name: str
|
100
|
+
agent_class: str
|
101
|
+
agent_module: Optional[str] = None
|
102
|
+
input_args: dict = field(default_factory=dict)
|
103
|
+
returns: Optional[Union[str, list, dict, tuple]] = None
|