oracle-ads 2.12.9__py3-none-any.whl → 2.12.10rc0__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 -4
- ads/aqua/common/enums.py +3 -0
- ads/aqua/common/utils.py +62 -2
- ads/aqua/data.py +2 -19
- ads/aqua/extension/finetune_handler.py +8 -14
- ads/aqua/extension/model_handler.py +19 -2
- ads/aqua/finetuning/constants.py +5 -2
- ads/aqua/finetuning/entities.py +64 -17
- ads/aqua/finetuning/finetuning.py +38 -54
- ads/aqua/model/entities.py +2 -1
- ads/aqua/model/model.py +61 -23
- 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 +12 -5
- ads/opctl/operator/lowcode/common/utils.py +11 -5
- 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/neuralprophet.py +10 -3
- ads/opctl/operator/lowcode/forecast/model/prophet.py +25 -18
- ads/opctl/operator/lowcode/forecast/schema.yaml +13 -0
- ads/opctl/operator/lowcode/forecast/utils.py +4 -3
- 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.10rc0.dist-info}/METADATA +7 -8
- {oracle_ads-2.12.9.dist-info → oracle_ads-2.12.10rc0.dist-info}/RECORD +60 -39
- {oracle_ads-2.12.9.dist-info → oracle_ads-2.12.10rc0.dist-info}/LICENSE.txt +0 -0
- {oracle_ads-2.12.9.dist-info → oracle_ads-2.12.10rc0.dist-info}/WHEEL +0 -0
- {oracle_ads-2.12.9.dist-info → oracle_ads-2.12.10rc0.dist-info}/entry_points.txt +0 -0
ads/aqua/model/model.py
CHANGED
@@ -1,5 +1,5 @@
|
|
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
|
import os
|
5
5
|
import pathlib
|
@@ -15,6 +15,7 @@ from oci.data_science.models import JobRun, Metadata, Model, UpdateModelDetails
|
|
15
15
|
from ads.aqua import ODSC_MODEL_COMPARTMENT_OCID, logger
|
16
16
|
from ads.aqua.app import AquaApp
|
17
17
|
from ads.aqua.common.enums import (
|
18
|
+
CustomInferenceContainerTypeFamily,
|
18
19
|
FineTuningContainerTypeFamily,
|
19
20
|
InferenceContainerTypeFamily,
|
20
21
|
Tags,
|
@@ -23,6 +24,7 @@ from ads.aqua.common.errors import AquaRuntimeError, AquaValueError
|
|
23
24
|
from ads.aqua.common.utils import (
|
24
25
|
LifecycleStatus,
|
25
26
|
_build_resource_identifier,
|
27
|
+
cleanup_local_hf_model_artifact,
|
26
28
|
copy_model_config,
|
27
29
|
create_word_icon,
|
28
30
|
generate_tei_cmd_var,
|
@@ -376,8 +378,10 @@ class AquaModelApp(AquaApp):
|
|
376
378
|
f"Failed to delete model:{model_id}. Only registered models or finetuned model can be deleted."
|
377
379
|
)
|
378
380
|
|
379
|
-
@telemetry(entry_point="plugin=model&action=
|
380
|
-
def edit_registered_model(
|
381
|
+
@telemetry(entry_point="plugin=model&action=edit", name="aqua")
|
382
|
+
def edit_registered_model(
|
383
|
+
self, id, inference_container, inference_container_uri, enable_finetuning, task
|
384
|
+
):
|
381
385
|
"""Edits the default config of unverified registered model.
|
382
386
|
|
383
387
|
Parameters
|
@@ -386,6 +390,8 @@ class AquaModelApp(AquaApp):
|
|
386
390
|
The model OCID.
|
387
391
|
inference_container: str.
|
388
392
|
The inference container family name
|
393
|
+
inference_container_uri: str
|
394
|
+
The inference container uri for embedding models
|
389
395
|
enable_finetuning: str
|
390
396
|
Flag to enable or disable finetuning over the model. Defaults to None
|
391
397
|
task:
|
@@ -401,19 +407,44 @@ class AquaModelApp(AquaApp):
|
|
401
407
|
if ds_model.freeform_tags.get(Tags.BASE_MODEL_CUSTOM, None):
|
402
408
|
if ds_model.freeform_tags.get(Tags.AQUA_SERVICE_MODEL_TAG, None):
|
403
409
|
raise AquaRuntimeError(
|
404
|
-
|
410
|
+
"Only registered unverified models can be edited."
|
405
411
|
)
|
406
412
|
else:
|
407
413
|
custom_metadata_list = ds_model.custom_metadata_list
|
408
414
|
freeform_tags = ds_model.freeform_tags
|
409
415
|
if inference_container:
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
416
|
+
if (
|
417
|
+
inference_container in CustomInferenceContainerTypeFamily
|
418
|
+
and inference_container_uri is None
|
419
|
+
):
|
420
|
+
raise AquaRuntimeError(
|
421
|
+
"Inference container URI must be provided."
|
422
|
+
)
|
423
|
+
else:
|
424
|
+
custom_metadata_list.add(
|
425
|
+
key=ModelCustomMetadataFields.DEPLOYMENT_CONTAINER,
|
426
|
+
value=inference_container,
|
427
|
+
category=MetadataCustomCategory.OTHER,
|
428
|
+
description="Deployment container mapping for SMC",
|
429
|
+
replace=True,
|
430
|
+
)
|
431
|
+
if inference_container_uri:
|
432
|
+
if (
|
433
|
+
inference_container in CustomInferenceContainerTypeFamily
|
434
|
+
or inference_container is None
|
435
|
+
):
|
436
|
+
custom_metadata_list.add(
|
437
|
+
key=ModelCustomMetadataFields.DEPLOYMENT_CONTAINER_URI,
|
438
|
+
value=inference_container_uri,
|
439
|
+
category=MetadataCustomCategory.OTHER,
|
440
|
+
description=f"Inference container URI for {ds_model.display_name}",
|
441
|
+
replace=True,
|
442
|
+
)
|
443
|
+
else:
|
444
|
+
raise AquaRuntimeError(
|
445
|
+
f"Inference container URI can be edited only with container values: {CustomInferenceContainerTypeFamily.values()}"
|
446
|
+
)
|
447
|
+
|
417
448
|
if enable_finetuning is not None:
|
418
449
|
if enable_finetuning.lower() == "true":
|
419
450
|
custom_metadata_list.add(
|
@@ -448,9 +479,7 @@ class AquaModelApp(AquaApp):
|
|
448
479
|
)
|
449
480
|
AquaApp().update_model(id, update_model_details)
|
450
481
|
else:
|
451
|
-
raise AquaRuntimeError(
|
452
|
-
f"Failed to edit model:{id}. Only registered unverified models can be edited."
|
453
|
-
)
|
482
|
+
raise AquaRuntimeError("Only registered unverified models can be edited.")
|
454
483
|
|
455
484
|
def _fetch_metric_from_metadata(
|
456
485
|
self,
|
@@ -869,8 +898,7 @@ class AquaModelApp(AquaApp):
|
|
869
898
|
# only add cmd vars if inference container is not an SMC
|
870
899
|
if (
|
871
900
|
inference_container not in smc_container_set
|
872
|
-
and inference_container
|
873
|
-
== InferenceContainerTypeFamily.AQUA_TEI_CONTAINER_FAMILY
|
901
|
+
and inference_container in CustomInferenceContainerTypeFamily.values()
|
874
902
|
):
|
875
903
|
cmd_vars = generate_tei_cmd_var(os_path)
|
876
904
|
metadata.add(
|
@@ -1322,20 +1350,20 @@ class AquaModelApp(AquaApp):
|
|
1322
1350
|
Returns
|
1323
1351
|
-------
|
1324
1352
|
model_artifact_path (str): Location where the model artifacts are downloaded.
|
1325
|
-
|
1326
1353
|
"""
|
1327
1354
|
# Download the model from hub
|
1328
|
-
if
|
1329
|
-
local_dir = os.path.join(
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1355
|
+
if local_dir:
|
1356
|
+
local_dir = os.path.join(local_dir, model_name)
|
1357
|
+
os.makedirs(local_dir, exist_ok=True)
|
1358
|
+
|
1359
|
+
# if local_dir is not set, the return value points to the cached data folder
|
1360
|
+
local_dir = snapshot_download(
|
1333
1361
|
repo_id=model_name,
|
1334
1362
|
local_dir=local_dir,
|
1335
1363
|
allow_patterns=allow_patterns,
|
1336
1364
|
ignore_patterns=ignore_patterns,
|
1337
1365
|
)
|
1338
|
-
# Upload to object storage
|
1366
|
+
# Upload to object storage
|
1339
1367
|
model_artifact_path = upload_folder(
|
1340
1368
|
os_path=os_path,
|
1341
1369
|
local_dir=local_dir,
|
@@ -1365,6 +1393,8 @@ class AquaModelApp(AquaApp):
|
|
1365
1393
|
ignore_patterns (list): Model files matching any of the patterns are not downloaded.
|
1366
1394
|
Example: ["*.json"] will ignore all .json files. ["folder/*"] will ignore all files under `folder`.
|
1367
1395
|
Patterns are Standard Wildcards (globbing patterns) and rules can be found here: https://docs.python.org/3/library/fnmatch.html
|
1396
|
+
cleanup_model_cache (bool): Deletes downloaded files from local machine after model is successfully
|
1397
|
+
registered. Set to True by default.
|
1368
1398
|
|
1369
1399
|
Returns:
|
1370
1400
|
AquaModel:
|
@@ -1474,6 +1504,14 @@ class AquaModelApp(AquaApp):
|
|
1474
1504
|
detail=validation_result.telemetry_model_name,
|
1475
1505
|
)
|
1476
1506
|
|
1507
|
+
if (
|
1508
|
+
import_model_details.download_from_hf
|
1509
|
+
and import_model_details.cleanup_model_cache
|
1510
|
+
):
|
1511
|
+
cleanup_local_hf_model_artifact(
|
1512
|
+
model_name=model_name, local_dir=import_model_details.local_dir
|
1513
|
+
)
|
1514
|
+
|
1477
1515
|
return AquaModel(**aqua_model_attributes)
|
1478
1516
|
|
1479
1517
|
def _if_show(self, model: DataScienceModel) -> bool:
|
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
|