genesis-flow 1.0.0__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.
- genesis_flow-1.0.0.dist-info/METADATA +822 -0
- genesis_flow-1.0.0.dist-info/RECORD +645 -0
- genesis_flow-1.0.0.dist-info/WHEEL +5 -0
- genesis_flow-1.0.0.dist-info/entry_points.txt +19 -0
- genesis_flow-1.0.0.dist-info/licenses/LICENSE.txt +202 -0
- genesis_flow-1.0.0.dist-info/top_level.txt +1 -0
- mlflow/__init__.py +367 -0
- mlflow/__main__.py +3 -0
- mlflow/ag2/__init__.py +56 -0
- mlflow/ag2/ag2_logger.py +294 -0
- mlflow/anthropic/__init__.py +40 -0
- mlflow/anthropic/autolog.py +129 -0
- mlflow/anthropic/chat.py +144 -0
- mlflow/artifacts/__init__.py +268 -0
- mlflow/autogen/__init__.py +144 -0
- mlflow/autogen/chat.py +142 -0
- mlflow/azure/__init__.py +26 -0
- mlflow/azure/auth_handler.py +257 -0
- mlflow/azure/client.py +319 -0
- mlflow/azure/config.py +120 -0
- mlflow/azure/connection_factory.py +340 -0
- mlflow/azure/exceptions.py +27 -0
- mlflow/azure/stores.py +327 -0
- mlflow/azure/utils.py +183 -0
- mlflow/bedrock/__init__.py +45 -0
- mlflow/bedrock/_autolog.py +202 -0
- mlflow/bedrock/chat.py +122 -0
- mlflow/bedrock/stream.py +160 -0
- mlflow/bedrock/utils.py +43 -0
- mlflow/cli.py +707 -0
- mlflow/client.py +12 -0
- mlflow/config/__init__.py +56 -0
- mlflow/crewai/__init__.py +79 -0
- mlflow/crewai/autolog.py +253 -0
- mlflow/crewai/chat.py +29 -0
- mlflow/data/__init__.py +75 -0
- mlflow/data/artifact_dataset_sources.py +170 -0
- mlflow/data/code_dataset_source.py +40 -0
- mlflow/data/dataset.py +123 -0
- mlflow/data/dataset_registry.py +168 -0
- mlflow/data/dataset_source.py +110 -0
- mlflow/data/dataset_source_registry.py +219 -0
- mlflow/data/delta_dataset_source.py +167 -0
- mlflow/data/digest_utils.py +108 -0
- mlflow/data/evaluation_dataset.py +562 -0
- mlflow/data/filesystem_dataset_source.py +81 -0
- mlflow/data/http_dataset_source.py +145 -0
- mlflow/data/huggingface_dataset.py +258 -0
- mlflow/data/huggingface_dataset_source.py +118 -0
- mlflow/data/meta_dataset.py +104 -0
- mlflow/data/numpy_dataset.py +223 -0
- mlflow/data/pandas_dataset.py +231 -0
- mlflow/data/polars_dataset.py +352 -0
- mlflow/data/pyfunc_dataset_mixin.py +31 -0
- mlflow/data/schema.py +76 -0
- mlflow/data/sources.py +1 -0
- mlflow/data/spark_dataset.py +406 -0
- mlflow/data/spark_dataset_source.py +74 -0
- mlflow/data/spark_delta_utils.py +118 -0
- mlflow/data/tensorflow_dataset.py +350 -0
- mlflow/data/uc_volume_dataset_source.py +81 -0
- mlflow/db.py +27 -0
- mlflow/dspy/__init__.py +17 -0
- mlflow/dspy/autolog.py +197 -0
- mlflow/dspy/callback.py +398 -0
- mlflow/dspy/constant.py +1 -0
- mlflow/dspy/load.py +93 -0
- mlflow/dspy/save.py +393 -0
- mlflow/dspy/util.py +109 -0
- mlflow/dspy/wrapper.py +226 -0
- mlflow/entities/__init__.py +104 -0
- mlflow/entities/_mlflow_object.py +52 -0
- mlflow/entities/assessment.py +545 -0
- mlflow/entities/assessment_error.py +80 -0
- mlflow/entities/assessment_source.py +141 -0
- mlflow/entities/dataset.py +92 -0
- mlflow/entities/dataset_input.py +51 -0
- mlflow/entities/dataset_summary.py +62 -0
- mlflow/entities/document.py +48 -0
- mlflow/entities/experiment.py +109 -0
- mlflow/entities/experiment_tag.py +35 -0
- mlflow/entities/file_info.py +45 -0
- mlflow/entities/input_tag.py +35 -0
- mlflow/entities/lifecycle_stage.py +35 -0
- mlflow/entities/logged_model.py +228 -0
- mlflow/entities/logged_model_input.py +26 -0
- mlflow/entities/logged_model_output.py +32 -0
- mlflow/entities/logged_model_parameter.py +46 -0
- mlflow/entities/logged_model_status.py +74 -0
- mlflow/entities/logged_model_tag.py +33 -0
- mlflow/entities/metric.py +200 -0
- mlflow/entities/model_registry/__init__.py +29 -0
- mlflow/entities/model_registry/_model_registry_entity.py +13 -0
- mlflow/entities/model_registry/model_version.py +243 -0
- mlflow/entities/model_registry/model_version_deployment_job_run_state.py +44 -0
- mlflow/entities/model_registry/model_version_deployment_job_state.py +70 -0
- mlflow/entities/model_registry/model_version_search.py +25 -0
- mlflow/entities/model_registry/model_version_stages.py +25 -0
- mlflow/entities/model_registry/model_version_status.py +35 -0
- mlflow/entities/model_registry/model_version_tag.py +35 -0
- mlflow/entities/model_registry/prompt.py +73 -0
- mlflow/entities/model_registry/prompt_version.py +244 -0
- mlflow/entities/model_registry/registered_model.py +175 -0
- mlflow/entities/model_registry/registered_model_alias.py +35 -0
- mlflow/entities/model_registry/registered_model_deployment_job_state.py +39 -0
- mlflow/entities/model_registry/registered_model_search.py +25 -0
- mlflow/entities/model_registry/registered_model_tag.py +35 -0
- mlflow/entities/multipart_upload.py +74 -0
- mlflow/entities/param.py +49 -0
- mlflow/entities/run.py +97 -0
- mlflow/entities/run_data.py +84 -0
- mlflow/entities/run_info.py +188 -0
- mlflow/entities/run_inputs.py +59 -0
- mlflow/entities/run_outputs.py +43 -0
- mlflow/entities/run_status.py +41 -0
- mlflow/entities/run_tag.py +36 -0
- mlflow/entities/source_type.py +31 -0
- mlflow/entities/span.py +774 -0
- mlflow/entities/span_event.py +96 -0
- mlflow/entities/span_status.py +102 -0
- mlflow/entities/trace.py +317 -0
- mlflow/entities/trace_data.py +71 -0
- mlflow/entities/trace_info.py +220 -0
- mlflow/entities/trace_info_v2.py +162 -0
- mlflow/entities/trace_location.py +173 -0
- mlflow/entities/trace_state.py +39 -0
- mlflow/entities/trace_status.py +68 -0
- mlflow/entities/view_type.py +51 -0
- mlflow/environment_variables.py +866 -0
- mlflow/evaluation/__init__.py +16 -0
- mlflow/evaluation/assessment.py +369 -0
- mlflow/evaluation/evaluation.py +411 -0
- mlflow/evaluation/evaluation_tag.py +61 -0
- mlflow/evaluation/fluent.py +48 -0
- mlflow/evaluation/utils.py +201 -0
- mlflow/exceptions.py +213 -0
- mlflow/experiments.py +140 -0
- mlflow/gemini/__init__.py +81 -0
- mlflow/gemini/autolog.py +186 -0
- mlflow/gemini/chat.py +261 -0
- mlflow/genai/__init__.py +71 -0
- mlflow/genai/datasets/__init__.py +67 -0
- mlflow/genai/datasets/evaluation_dataset.py +131 -0
- mlflow/genai/evaluation/__init__.py +3 -0
- mlflow/genai/evaluation/base.py +411 -0
- mlflow/genai/evaluation/constant.py +23 -0
- mlflow/genai/evaluation/utils.py +244 -0
- mlflow/genai/judges/__init__.py +21 -0
- mlflow/genai/judges/databricks.py +404 -0
- mlflow/genai/label_schemas/__init__.py +153 -0
- mlflow/genai/label_schemas/label_schemas.py +209 -0
- mlflow/genai/labeling/__init__.py +159 -0
- mlflow/genai/labeling/labeling.py +250 -0
- mlflow/genai/optimize/__init__.py +13 -0
- mlflow/genai/optimize/base.py +198 -0
- mlflow/genai/optimize/optimizers/__init__.py +4 -0
- mlflow/genai/optimize/optimizers/base_optimizer.py +38 -0
- mlflow/genai/optimize/optimizers/dspy_mipro_optimizer.py +221 -0
- mlflow/genai/optimize/optimizers/dspy_optimizer.py +91 -0
- mlflow/genai/optimize/optimizers/utils/dspy_mipro_callback.py +76 -0
- mlflow/genai/optimize/optimizers/utils/dspy_mipro_utils.py +18 -0
- mlflow/genai/optimize/types.py +75 -0
- mlflow/genai/optimize/util.py +30 -0
- mlflow/genai/prompts/__init__.py +206 -0
- mlflow/genai/scheduled_scorers.py +431 -0
- mlflow/genai/scorers/__init__.py +26 -0
- mlflow/genai/scorers/base.py +492 -0
- mlflow/genai/scorers/builtin_scorers.py +765 -0
- mlflow/genai/scorers/scorer_utils.py +138 -0
- mlflow/genai/scorers/validation.py +165 -0
- mlflow/genai/utils/data_validation.py +146 -0
- mlflow/genai/utils/enum_utils.py +23 -0
- mlflow/genai/utils/trace_utils.py +211 -0
- mlflow/groq/__init__.py +42 -0
- mlflow/groq/_groq_autolog.py +74 -0
- mlflow/johnsnowlabs/__init__.py +888 -0
- mlflow/langchain/__init__.py +24 -0
- mlflow/langchain/api_request_parallel_processor.py +330 -0
- mlflow/langchain/autolog.py +147 -0
- mlflow/langchain/chat_agent_langgraph.py +340 -0
- mlflow/langchain/constant.py +1 -0
- mlflow/langchain/constants.py +1 -0
- mlflow/langchain/databricks_dependencies.py +444 -0
- mlflow/langchain/langchain_tracer.py +597 -0
- mlflow/langchain/model.py +919 -0
- mlflow/langchain/output_parsers.py +142 -0
- mlflow/langchain/retriever_chain.py +153 -0
- mlflow/langchain/runnables.py +527 -0
- mlflow/langchain/utils/chat.py +402 -0
- mlflow/langchain/utils/logging.py +671 -0
- mlflow/langchain/utils/serialization.py +36 -0
- mlflow/legacy_databricks_cli/__init__.py +0 -0
- mlflow/legacy_databricks_cli/configure/__init__.py +0 -0
- mlflow/legacy_databricks_cli/configure/provider.py +482 -0
- mlflow/litellm/__init__.py +175 -0
- mlflow/llama_index/__init__.py +22 -0
- mlflow/llama_index/autolog.py +55 -0
- mlflow/llama_index/chat.py +43 -0
- mlflow/llama_index/constant.py +1 -0
- mlflow/llama_index/model.py +577 -0
- mlflow/llama_index/pyfunc_wrapper.py +332 -0
- mlflow/llama_index/serialize_objects.py +188 -0
- mlflow/llama_index/tracer.py +561 -0
- mlflow/metrics/__init__.py +479 -0
- mlflow/metrics/base.py +39 -0
- mlflow/metrics/genai/__init__.py +25 -0
- mlflow/metrics/genai/base.py +101 -0
- mlflow/metrics/genai/genai_metric.py +771 -0
- mlflow/metrics/genai/metric_definitions.py +450 -0
- mlflow/metrics/genai/model_utils.py +371 -0
- mlflow/metrics/genai/prompt_template.py +68 -0
- mlflow/metrics/genai/prompts/__init__.py +0 -0
- mlflow/metrics/genai/prompts/v1.py +422 -0
- mlflow/metrics/genai/utils.py +6 -0
- mlflow/metrics/metric_definitions.py +619 -0
- mlflow/mismatch.py +34 -0
- mlflow/mistral/__init__.py +34 -0
- mlflow/mistral/autolog.py +71 -0
- mlflow/mistral/chat.py +135 -0
- mlflow/ml_package_versions.py +452 -0
- mlflow/models/__init__.py +97 -0
- mlflow/models/auth_policy.py +83 -0
- mlflow/models/cli.py +354 -0
- mlflow/models/container/__init__.py +294 -0
- mlflow/models/container/scoring_server/__init__.py +0 -0
- mlflow/models/container/scoring_server/nginx.conf +39 -0
- mlflow/models/dependencies_schemas.py +287 -0
- mlflow/models/display_utils.py +158 -0
- mlflow/models/docker_utils.py +211 -0
- mlflow/models/evaluation/__init__.py +23 -0
- mlflow/models/evaluation/_shap_patch.py +64 -0
- mlflow/models/evaluation/artifacts.py +194 -0
- mlflow/models/evaluation/base.py +1811 -0
- mlflow/models/evaluation/calibration_curve.py +109 -0
- mlflow/models/evaluation/default_evaluator.py +996 -0
- mlflow/models/evaluation/deprecated.py +23 -0
- mlflow/models/evaluation/evaluator_registry.py +80 -0
- mlflow/models/evaluation/evaluators/classifier.py +704 -0
- mlflow/models/evaluation/evaluators/default.py +233 -0
- mlflow/models/evaluation/evaluators/regressor.py +96 -0
- mlflow/models/evaluation/evaluators/shap.py +296 -0
- mlflow/models/evaluation/lift_curve.py +178 -0
- mlflow/models/evaluation/utils/metric.py +123 -0
- mlflow/models/evaluation/utils/trace.py +179 -0
- mlflow/models/evaluation/validation.py +434 -0
- mlflow/models/flavor_backend.py +93 -0
- mlflow/models/flavor_backend_registry.py +53 -0
- mlflow/models/model.py +1639 -0
- mlflow/models/model_config.py +150 -0
- mlflow/models/notebook_resources/agent_evaluation_template.html +235 -0
- mlflow/models/notebook_resources/eval_with_dataset_example.py +22 -0
- mlflow/models/notebook_resources/eval_with_synthetic_example.py +22 -0
- mlflow/models/python_api.py +369 -0
- mlflow/models/rag_signatures.py +128 -0
- mlflow/models/resources.py +321 -0
- mlflow/models/signature.py +662 -0
- mlflow/models/utils.py +2054 -0
- mlflow/models/wheeled_model.py +280 -0
- mlflow/openai/__init__.py +57 -0
- mlflow/openai/_agent_tracer.py +364 -0
- mlflow/openai/api_request_parallel_processor.py +131 -0
- mlflow/openai/autolog.py +509 -0
- mlflow/openai/constant.py +1 -0
- mlflow/openai/model.py +824 -0
- mlflow/openai/utils/chat_schema.py +367 -0
- mlflow/optuna/__init__.py +3 -0
- mlflow/optuna/storage.py +646 -0
- mlflow/plugins/__init__.py +72 -0
- mlflow/plugins/base.py +358 -0
- mlflow/plugins/builtin/__init__.py +24 -0
- mlflow/plugins/builtin/pytorch_plugin.py +150 -0
- mlflow/plugins/builtin/sklearn_plugin.py +158 -0
- mlflow/plugins/builtin/transformers_plugin.py +187 -0
- mlflow/plugins/cli.py +321 -0
- mlflow/plugins/discovery.py +340 -0
- mlflow/plugins/manager.py +465 -0
- mlflow/plugins/registry.py +316 -0
- mlflow/plugins/templates/framework_plugin_template.py +329 -0
- mlflow/prompt/constants.py +20 -0
- mlflow/prompt/promptlab_model.py +197 -0
- mlflow/prompt/registry_utils.py +248 -0
- mlflow/promptflow/__init__.py +495 -0
- mlflow/protos/__init__.py +0 -0
- mlflow/protos/assessments_pb2.py +174 -0
- mlflow/protos/databricks_artifacts_pb2.py +489 -0
- mlflow/protos/databricks_filesystem_service_pb2.py +196 -0
- mlflow/protos/databricks_managed_catalog_messages_pb2.py +95 -0
- mlflow/protos/databricks_managed_catalog_service_pb2.py +86 -0
- mlflow/protos/databricks_pb2.py +267 -0
- mlflow/protos/databricks_trace_server_pb2.py +374 -0
- mlflow/protos/databricks_uc_registry_messages_pb2.py +1249 -0
- mlflow/protos/databricks_uc_registry_service_pb2.py +170 -0
- mlflow/protos/facet_feature_statistics_pb2.py +296 -0
- mlflow/protos/internal_pb2.py +77 -0
- mlflow/protos/mlflow_artifacts_pb2.py +336 -0
- mlflow/protos/model_registry_pb2.py +1073 -0
- mlflow/protos/scalapb/__init__.py +0 -0
- mlflow/protos/scalapb/scalapb_pb2.py +104 -0
- mlflow/protos/service_pb2.py +2600 -0
- mlflow/protos/unity_catalog_oss_messages_pb2.py +457 -0
- mlflow/protos/unity_catalog_oss_service_pb2.py +130 -0
- mlflow/protos/unity_catalog_prompt_messages_pb2.py +447 -0
- mlflow/protos/unity_catalog_prompt_messages_pb2_grpc.py +24 -0
- mlflow/protos/unity_catalog_prompt_service_pb2.py +164 -0
- mlflow/protos/unity_catalog_prompt_service_pb2_grpc.py +785 -0
- mlflow/py.typed +0 -0
- mlflow/pydantic_ai/__init__.py +57 -0
- mlflow/pydantic_ai/autolog.py +173 -0
- mlflow/pyfunc/__init__.py +3844 -0
- mlflow/pyfunc/_mlflow_pyfunc_backend_predict.py +61 -0
- mlflow/pyfunc/backend.py +523 -0
- mlflow/pyfunc/context.py +78 -0
- mlflow/pyfunc/dbconnect_artifact_cache.py +144 -0
- mlflow/pyfunc/loaders/__init__.py +7 -0
- mlflow/pyfunc/loaders/chat_agent.py +117 -0
- mlflow/pyfunc/loaders/chat_model.py +125 -0
- mlflow/pyfunc/loaders/code_model.py +31 -0
- mlflow/pyfunc/loaders/responses_agent.py +112 -0
- mlflow/pyfunc/mlserver.py +46 -0
- mlflow/pyfunc/model.py +1473 -0
- mlflow/pyfunc/scoring_server/__init__.py +604 -0
- mlflow/pyfunc/scoring_server/app.py +7 -0
- mlflow/pyfunc/scoring_server/client.py +146 -0
- mlflow/pyfunc/spark_model_cache.py +48 -0
- mlflow/pyfunc/stdin_server.py +44 -0
- mlflow/pyfunc/utils/__init__.py +3 -0
- mlflow/pyfunc/utils/data_validation.py +224 -0
- mlflow/pyfunc/utils/environment.py +22 -0
- mlflow/pyfunc/utils/input_converter.py +47 -0
- mlflow/pyfunc/utils/serving_data_parser.py +11 -0
- mlflow/pytorch/__init__.py +1171 -0
- mlflow/pytorch/_lightning_autolog.py +580 -0
- mlflow/pytorch/_pytorch_autolog.py +50 -0
- mlflow/pytorch/pickle_module.py +35 -0
- mlflow/rfunc/__init__.py +42 -0
- mlflow/rfunc/backend.py +134 -0
- mlflow/runs.py +89 -0
- mlflow/server/__init__.py +302 -0
- mlflow/server/auth/__init__.py +1224 -0
- mlflow/server/auth/__main__.py +4 -0
- mlflow/server/auth/basic_auth.ini +6 -0
- mlflow/server/auth/cli.py +11 -0
- mlflow/server/auth/client.py +537 -0
- mlflow/server/auth/config.py +34 -0
- mlflow/server/auth/db/__init__.py +0 -0
- mlflow/server/auth/db/cli.py +18 -0
- mlflow/server/auth/db/migrations/__init__.py +0 -0
- mlflow/server/auth/db/migrations/alembic.ini +110 -0
- mlflow/server/auth/db/migrations/env.py +76 -0
- mlflow/server/auth/db/migrations/versions/8606fa83a998_initial_migration.py +51 -0
- mlflow/server/auth/db/migrations/versions/__init__.py +0 -0
- mlflow/server/auth/db/models.py +67 -0
- mlflow/server/auth/db/utils.py +37 -0
- mlflow/server/auth/entities.py +165 -0
- mlflow/server/auth/logo.py +14 -0
- mlflow/server/auth/permissions.py +65 -0
- mlflow/server/auth/routes.py +18 -0
- mlflow/server/auth/sqlalchemy_store.py +263 -0
- mlflow/server/graphql/__init__.py +0 -0
- mlflow/server/graphql/autogenerated_graphql_schema.py +353 -0
- mlflow/server/graphql/graphql_custom_scalars.py +24 -0
- mlflow/server/graphql/graphql_errors.py +15 -0
- mlflow/server/graphql/graphql_no_batching.py +89 -0
- mlflow/server/graphql/graphql_schema_extensions.py +74 -0
- mlflow/server/handlers.py +3217 -0
- mlflow/server/prometheus_exporter.py +17 -0
- mlflow/server/validation.py +30 -0
- mlflow/shap/__init__.py +691 -0
- mlflow/sklearn/__init__.py +1994 -0
- mlflow/sklearn/utils.py +1041 -0
- mlflow/smolagents/__init__.py +66 -0
- mlflow/smolagents/autolog.py +139 -0
- mlflow/smolagents/chat.py +29 -0
- mlflow/store/__init__.py +10 -0
- mlflow/store/_unity_catalog/__init__.py +1 -0
- mlflow/store/_unity_catalog/lineage/__init__.py +1 -0
- mlflow/store/_unity_catalog/lineage/constants.py +2 -0
- mlflow/store/_unity_catalog/registry/__init__.py +6 -0
- mlflow/store/_unity_catalog/registry/prompt_info.py +75 -0
- mlflow/store/_unity_catalog/registry/rest_store.py +1740 -0
- mlflow/store/_unity_catalog/registry/uc_oss_rest_store.py +507 -0
- mlflow/store/_unity_catalog/registry/utils.py +121 -0
- mlflow/store/artifact/__init__.py +0 -0
- mlflow/store/artifact/artifact_repo.py +472 -0
- mlflow/store/artifact/artifact_repository_registry.py +154 -0
- mlflow/store/artifact/azure_blob_artifact_repo.py +275 -0
- mlflow/store/artifact/azure_data_lake_artifact_repo.py +295 -0
- mlflow/store/artifact/cli.py +141 -0
- mlflow/store/artifact/cloud_artifact_repo.py +332 -0
- mlflow/store/artifact/databricks_artifact_repo.py +729 -0
- mlflow/store/artifact/databricks_artifact_repo_resources.py +301 -0
- mlflow/store/artifact/databricks_logged_model_artifact_repo.py +93 -0
- mlflow/store/artifact/databricks_models_artifact_repo.py +216 -0
- mlflow/store/artifact/databricks_sdk_artifact_repo.py +134 -0
- mlflow/store/artifact/databricks_sdk_models_artifact_repo.py +97 -0
- mlflow/store/artifact/dbfs_artifact_repo.py +240 -0
- mlflow/store/artifact/ftp_artifact_repo.py +132 -0
- mlflow/store/artifact/gcs_artifact_repo.py +296 -0
- mlflow/store/artifact/hdfs_artifact_repo.py +209 -0
- mlflow/store/artifact/http_artifact_repo.py +218 -0
- mlflow/store/artifact/local_artifact_repo.py +142 -0
- mlflow/store/artifact/mlflow_artifacts_repo.py +94 -0
- mlflow/store/artifact/models_artifact_repo.py +259 -0
- mlflow/store/artifact/optimized_s3_artifact_repo.py +356 -0
- mlflow/store/artifact/presigned_url_artifact_repo.py +173 -0
- mlflow/store/artifact/r2_artifact_repo.py +70 -0
- mlflow/store/artifact/runs_artifact_repo.py +265 -0
- mlflow/store/artifact/s3_artifact_repo.py +330 -0
- mlflow/store/artifact/sftp_artifact_repo.py +141 -0
- mlflow/store/artifact/uc_volume_artifact_repo.py +76 -0
- mlflow/store/artifact/unity_catalog_models_artifact_repo.py +168 -0
- mlflow/store/artifact/unity_catalog_oss_models_artifact_repo.py +168 -0
- mlflow/store/artifact/utils/__init__.py +0 -0
- mlflow/store/artifact/utils/models.py +148 -0
- mlflow/store/db/__init__.py +0 -0
- mlflow/store/db/base_sql_model.py +3 -0
- mlflow/store/db/db_types.py +10 -0
- mlflow/store/db/utils.py +314 -0
- mlflow/store/db_migrations/__init__.py +0 -0
- mlflow/store/db_migrations/alembic.ini +74 -0
- mlflow/store/db_migrations/env.py +84 -0
- mlflow/store/db_migrations/versions/0584bdc529eb_add_cascading_deletion_to_datasets_from_experiments.py +88 -0
- mlflow/store/db_migrations/versions/0a8213491aaa_drop_duplicate_killed_constraint.py +49 -0
- mlflow/store/db_migrations/versions/0c779009ac13_add_deleted_time_field_to_runs_table.py +24 -0
- mlflow/store/db_migrations/versions/181f10493468_allow_nulls_for_metric_values.py +35 -0
- mlflow/store/db_migrations/versions/27a6a02d2cf1_add_model_version_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/2b4d017a5e9b_add_model_registry_tables_to_db.py +77 -0
- mlflow/store/db_migrations/versions/2d6e25af4d3e_increase_max_param_val_length.py +33 -0
- mlflow/store/db_migrations/versions/3500859a5d39_add_model_aliases_table.py +50 -0
- mlflow/store/db_migrations/versions/39d1c3be5f05_add_is_nan_constraint_for_metrics_tables_if_necessary.py +41 -0
- mlflow/store/db_migrations/versions/400f98739977_add_logged_model_tables.py +123 -0
- mlflow/store/db_migrations/versions/4465047574b1_increase_max_dataset_schema_size.py +38 -0
- mlflow/store/db_migrations/versions/451aebb31d03_add_metric_step.py +35 -0
- mlflow/store/db_migrations/versions/5b0e9adcef9c_add_cascade_deletion_to_trace_tables_fk.py +40 -0
- mlflow/store/db_migrations/versions/6953534de441_add_step_to_inputs_table.py +25 -0
- mlflow/store/db_migrations/versions/728d730b5ebd_add_registered_model_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/7ac759974ad8_update_run_tags_with_larger_limit.py +36 -0
- mlflow/store/db_migrations/versions/7f2a7d5fae7d_add_datasets_inputs_input_tags_tables.py +82 -0
- mlflow/store/db_migrations/versions/84291f40a231_add_run_link_to_model_version.py +26 -0
- mlflow/store/db_migrations/versions/867495a8f9d4_add_trace_tables.py +90 -0
- mlflow/store/db_migrations/versions/89d4b8295536_create_latest_metrics_table.py +169 -0
- mlflow/store/db_migrations/versions/90e64c465722_migrate_user_column_to_tags.py +64 -0
- mlflow/store/db_migrations/versions/97727af70f4d_creation_time_last_update_time_experiments.py +25 -0
- mlflow/store/db_migrations/versions/__init__.py +0 -0
- mlflow/store/db_migrations/versions/a8c4a736bde6_allow_nulls_for_run_id.py +27 -0
- mlflow/store/db_migrations/versions/acf3f17fdcc7_add_storage_location_field_to_model_.py +29 -0
- mlflow/store/db_migrations/versions/bd07f7e963c5_create_index_on_run_uuid.py +26 -0
- mlflow/store/db_migrations/versions/bda7b8c39065_increase_model_version_tag_value_limit.py +38 -0
- mlflow/store/db_migrations/versions/c48cb773bb87_reset_default_value_for_is_nan_in_metrics_table_for_mysql.py +41 -0
- mlflow/store/db_migrations/versions/cbc13b556ace_add_v3_trace_schema_columns.py +31 -0
- mlflow/store/db_migrations/versions/cc1f77228345_change_param_value_length_to_500.py +34 -0
- mlflow/store/db_migrations/versions/cfd24bdc0731_update_run_status_constraint_with_killed.py +78 -0
- mlflow/store/db_migrations/versions/df50e92ffc5e_add_experiment_tags_table.py +38 -0
- mlflow/store/db_migrations/versions/f5a4f2784254_increase_run_tag_value_limit.py +36 -0
- mlflow/store/entities/__init__.py +3 -0
- mlflow/store/entities/paged_list.py +18 -0
- mlflow/store/model_registry/__init__.py +10 -0
- mlflow/store/model_registry/abstract_store.py +1081 -0
- mlflow/store/model_registry/base_rest_store.py +44 -0
- mlflow/store/model_registry/databricks_workspace_model_registry_rest_store.py +37 -0
- mlflow/store/model_registry/dbmodels/__init__.py +0 -0
- mlflow/store/model_registry/dbmodels/models.py +206 -0
- mlflow/store/model_registry/file_store.py +1091 -0
- mlflow/store/model_registry/rest_store.py +481 -0
- mlflow/store/model_registry/sqlalchemy_store.py +1286 -0
- mlflow/store/tracking/__init__.py +23 -0
- mlflow/store/tracking/abstract_store.py +816 -0
- mlflow/store/tracking/dbmodels/__init__.py +0 -0
- mlflow/store/tracking/dbmodels/initial_models.py +243 -0
- mlflow/store/tracking/dbmodels/models.py +1073 -0
- mlflow/store/tracking/file_store.py +2438 -0
- mlflow/store/tracking/postgres_managed_identity.py +146 -0
- mlflow/store/tracking/rest_store.py +1131 -0
- mlflow/store/tracking/sqlalchemy_store.py +2785 -0
- mlflow/system_metrics/__init__.py +61 -0
- mlflow/system_metrics/metrics/__init__.py +0 -0
- mlflow/system_metrics/metrics/base_metrics_monitor.py +32 -0
- mlflow/system_metrics/metrics/cpu_monitor.py +23 -0
- mlflow/system_metrics/metrics/disk_monitor.py +21 -0
- mlflow/system_metrics/metrics/gpu_monitor.py +71 -0
- mlflow/system_metrics/metrics/network_monitor.py +34 -0
- mlflow/system_metrics/metrics/rocm_monitor.py +123 -0
- mlflow/system_metrics/system_metrics_monitor.py +198 -0
- mlflow/tracing/__init__.py +16 -0
- mlflow/tracing/assessment.py +356 -0
- mlflow/tracing/client.py +531 -0
- mlflow/tracing/config.py +125 -0
- mlflow/tracing/constant.py +105 -0
- mlflow/tracing/destination.py +81 -0
- mlflow/tracing/display/__init__.py +40 -0
- mlflow/tracing/display/display_handler.py +196 -0
- mlflow/tracing/export/async_export_queue.py +186 -0
- mlflow/tracing/export/inference_table.py +138 -0
- mlflow/tracing/export/mlflow_v3.py +137 -0
- mlflow/tracing/export/utils.py +70 -0
- mlflow/tracing/fluent.py +1417 -0
- mlflow/tracing/processor/base_mlflow.py +199 -0
- mlflow/tracing/processor/inference_table.py +175 -0
- mlflow/tracing/processor/mlflow_v3.py +47 -0
- mlflow/tracing/processor/otel.py +73 -0
- mlflow/tracing/provider.py +487 -0
- mlflow/tracing/trace_manager.py +200 -0
- mlflow/tracing/utils/__init__.py +616 -0
- mlflow/tracing/utils/artifact_utils.py +28 -0
- mlflow/tracing/utils/copy.py +55 -0
- mlflow/tracing/utils/environment.py +55 -0
- mlflow/tracing/utils/exception.py +21 -0
- mlflow/tracing/utils/once.py +35 -0
- mlflow/tracing/utils/otlp.py +63 -0
- mlflow/tracing/utils/processor.py +54 -0
- mlflow/tracing/utils/search.py +292 -0
- mlflow/tracing/utils/timeout.py +250 -0
- mlflow/tracing/utils/token.py +19 -0
- mlflow/tracing/utils/truncation.py +124 -0
- mlflow/tracing/utils/warning.py +76 -0
- mlflow/tracking/__init__.py +39 -0
- mlflow/tracking/_model_registry/__init__.py +1 -0
- mlflow/tracking/_model_registry/client.py +764 -0
- mlflow/tracking/_model_registry/fluent.py +853 -0
- mlflow/tracking/_model_registry/registry.py +67 -0
- mlflow/tracking/_model_registry/utils.py +251 -0
- mlflow/tracking/_tracking_service/__init__.py +0 -0
- mlflow/tracking/_tracking_service/client.py +883 -0
- mlflow/tracking/_tracking_service/registry.py +56 -0
- mlflow/tracking/_tracking_service/utils.py +275 -0
- mlflow/tracking/artifact_utils.py +179 -0
- mlflow/tracking/client.py +5900 -0
- mlflow/tracking/context/__init__.py +0 -0
- mlflow/tracking/context/abstract_context.py +35 -0
- mlflow/tracking/context/databricks_cluster_context.py +15 -0
- mlflow/tracking/context/databricks_command_context.py +15 -0
- mlflow/tracking/context/databricks_job_context.py +49 -0
- mlflow/tracking/context/databricks_notebook_context.py +41 -0
- mlflow/tracking/context/databricks_repo_context.py +43 -0
- mlflow/tracking/context/default_context.py +51 -0
- mlflow/tracking/context/git_context.py +32 -0
- mlflow/tracking/context/registry.py +98 -0
- mlflow/tracking/context/system_environment_context.py +15 -0
- mlflow/tracking/default_experiment/__init__.py +1 -0
- mlflow/tracking/default_experiment/abstract_context.py +43 -0
- mlflow/tracking/default_experiment/databricks_notebook_experiment_provider.py +44 -0
- mlflow/tracking/default_experiment/registry.py +75 -0
- mlflow/tracking/fluent.py +3595 -0
- mlflow/tracking/metric_value_conversion_utils.py +93 -0
- mlflow/tracking/multimedia.py +206 -0
- mlflow/tracking/registry.py +86 -0
- mlflow/tracking/request_auth/__init__.py +0 -0
- mlflow/tracking/request_auth/abstract_request_auth_provider.py +34 -0
- mlflow/tracking/request_auth/registry.py +60 -0
- mlflow/tracking/request_header/__init__.py +0 -0
- mlflow/tracking/request_header/abstract_request_header_provider.py +36 -0
- mlflow/tracking/request_header/databricks_request_header_provider.py +38 -0
- mlflow/tracking/request_header/default_request_header_provider.py +17 -0
- mlflow/tracking/request_header/registry.py +79 -0
- mlflow/transformers/__init__.py +2982 -0
- mlflow/transformers/flavor_config.py +258 -0
- mlflow/transformers/hub_utils.py +83 -0
- mlflow/transformers/llm_inference_utils.py +468 -0
- mlflow/transformers/model_io.py +301 -0
- mlflow/transformers/peft.py +51 -0
- mlflow/transformers/signature.py +183 -0
- mlflow/transformers/torch_utils.py +55 -0
- mlflow/types/__init__.py +21 -0
- mlflow/types/agent.py +270 -0
- mlflow/types/chat.py +240 -0
- mlflow/types/llm.py +935 -0
- mlflow/types/responses.py +139 -0
- mlflow/types/responses_helpers.py +416 -0
- mlflow/types/schema.py +1505 -0
- mlflow/types/type_hints.py +647 -0
- mlflow/types/utils.py +753 -0
- mlflow/utils/__init__.py +283 -0
- mlflow/utils/_capture_modules.py +256 -0
- mlflow/utils/_capture_transformers_modules.py +75 -0
- mlflow/utils/_spark_utils.py +201 -0
- mlflow/utils/_unity_catalog_oss_utils.py +97 -0
- mlflow/utils/_unity_catalog_utils.py +479 -0
- mlflow/utils/annotations.py +218 -0
- mlflow/utils/arguments_utils.py +16 -0
- mlflow/utils/async_logging/__init__.py +1 -0
- mlflow/utils/async_logging/async_artifacts_logging_queue.py +258 -0
- mlflow/utils/async_logging/async_logging_queue.py +366 -0
- mlflow/utils/async_logging/run_artifact.py +38 -0
- mlflow/utils/async_logging/run_batch.py +58 -0
- mlflow/utils/async_logging/run_operations.py +49 -0
- mlflow/utils/autologging_utils/__init__.py +737 -0
- mlflow/utils/autologging_utils/client.py +432 -0
- mlflow/utils/autologging_utils/config.py +33 -0
- mlflow/utils/autologging_utils/events.py +294 -0
- mlflow/utils/autologging_utils/logging_and_warnings.py +328 -0
- mlflow/utils/autologging_utils/metrics_queue.py +71 -0
- mlflow/utils/autologging_utils/safety.py +1104 -0
- mlflow/utils/autologging_utils/versioning.py +95 -0
- mlflow/utils/checkpoint_utils.py +206 -0
- mlflow/utils/class_utils.py +6 -0
- mlflow/utils/cli_args.py +257 -0
- mlflow/utils/conda.py +354 -0
- mlflow/utils/credentials.py +231 -0
- mlflow/utils/data_utils.py +17 -0
- mlflow/utils/databricks_utils.py +1436 -0
- mlflow/utils/docstring_utils.py +477 -0
- mlflow/utils/doctor.py +133 -0
- mlflow/utils/download_cloud_file_chunk.py +43 -0
- mlflow/utils/env_manager.py +16 -0
- mlflow/utils/env_pack.py +131 -0
- mlflow/utils/environment.py +1009 -0
- mlflow/utils/exception_utils.py +14 -0
- mlflow/utils/file_utils.py +978 -0
- mlflow/utils/git_utils.py +77 -0
- mlflow/utils/gorilla.py +797 -0
- mlflow/utils/import_hooks/__init__.py +363 -0
- mlflow/utils/lazy_load.py +51 -0
- mlflow/utils/logging_utils.py +168 -0
- mlflow/utils/mime_type_utils.py +58 -0
- mlflow/utils/mlflow_tags.py +103 -0
- mlflow/utils/model_utils.py +486 -0
- mlflow/utils/name_utils.py +346 -0
- mlflow/utils/nfs_on_spark.py +62 -0
- mlflow/utils/openai_utils.py +164 -0
- mlflow/utils/os.py +12 -0
- mlflow/utils/oss_registry_utils.py +29 -0
- mlflow/utils/plugins.py +17 -0
- mlflow/utils/process.py +182 -0
- mlflow/utils/promptlab_utils.py +146 -0
- mlflow/utils/proto_json_utils.py +743 -0
- mlflow/utils/pydantic_utils.py +54 -0
- mlflow/utils/request_utils.py +279 -0
- mlflow/utils/requirements_utils.py +704 -0
- mlflow/utils/rest_utils.py +673 -0
- mlflow/utils/search_logged_model_utils.py +127 -0
- mlflow/utils/search_utils.py +2111 -0
- mlflow/utils/secure_loading.py +221 -0
- mlflow/utils/security_validation.py +384 -0
- mlflow/utils/server_cli_utils.py +61 -0
- mlflow/utils/spark_utils.py +15 -0
- mlflow/utils/string_utils.py +138 -0
- mlflow/utils/thread_utils.py +63 -0
- mlflow/utils/time.py +54 -0
- mlflow/utils/timeout.py +42 -0
- mlflow/utils/uri.py +572 -0
- mlflow/utils/validation.py +662 -0
- mlflow/utils/virtualenv.py +458 -0
- mlflow/utils/warnings_utils.py +25 -0
- mlflow/utils/yaml_utils.py +179 -0
- mlflow/version.py +24 -0
mlflow/ag2/ag2_logger.py
ADDED
@@ -0,0 +1,294 @@
|
|
1
|
+
import functools
|
2
|
+
import logging
|
3
|
+
import time
|
4
|
+
import uuid
|
5
|
+
from dataclasses import dataclass, field
|
6
|
+
from datetime import datetime, timezone
|
7
|
+
from typing import Any, Optional, Union
|
8
|
+
|
9
|
+
from autogen import Agent, ConversableAgent
|
10
|
+
from autogen.logger.base_logger import BaseLogger
|
11
|
+
from openai.types.chat import ChatCompletion
|
12
|
+
|
13
|
+
from mlflow.entities.span import NoOpSpan, Span, SpanType
|
14
|
+
from mlflow.entities.span_event import SpanEvent
|
15
|
+
from mlflow.entities.span_status import SpanStatus, SpanStatusCode
|
16
|
+
from mlflow.tracing.constant import SpanAttributeKey, TokenUsageKey
|
17
|
+
from mlflow.tracing.fluent import start_span_no_context
|
18
|
+
from mlflow.tracing.utils import capture_function_input_args
|
19
|
+
from mlflow.utils.autologging_utils import autologging_is_disabled
|
20
|
+
from mlflow.utils.autologging_utils.safety import safe_patch
|
21
|
+
|
22
|
+
# For GroupChat, a single "received_message" events are passed around multiple
|
23
|
+
# internal layers and thus too verbose if we show them all. Therefore we ignore
|
24
|
+
# some of the message senders listed below.
|
25
|
+
_EXCLUDED_MESSAGE_SENDERS = ["chat_manager", "checking_agent"]
|
26
|
+
|
27
|
+
_logger = logging.getLogger(__name__)
|
28
|
+
|
29
|
+
|
30
|
+
FLAVOR_NAME = "ag2"
|
31
|
+
|
32
|
+
|
33
|
+
@dataclass
|
34
|
+
class ChatState:
|
35
|
+
"""
|
36
|
+
Represents the state of a chat session.
|
37
|
+
"""
|
38
|
+
|
39
|
+
# The root span object that scopes the entire single chat session. All spans
|
40
|
+
# such as LLM, function calls, in the chat session should be children of this span.
|
41
|
+
session_span: Optional[Span] = None
|
42
|
+
# The last message object in the chat session.
|
43
|
+
last_message: Optional[Any] = None
|
44
|
+
# The timestamp (ns) of the last message in the chat session.
|
45
|
+
last_message_timestamp: int = 0
|
46
|
+
# LLM/Tool Spans created after the last message in the chat session.
|
47
|
+
# We consider them as operations for generating the next message and
|
48
|
+
# re-locate them under the corresponding message span.
|
49
|
+
pending_spans: list[Span] = field(default_factory=list)
|
50
|
+
|
51
|
+
def clear(self):
|
52
|
+
self.session_span = None
|
53
|
+
self.last_message = None
|
54
|
+
self.last_message_timestamp = 0
|
55
|
+
self.pending_spans = []
|
56
|
+
|
57
|
+
|
58
|
+
def _catch_exception(func):
|
59
|
+
def wrapper(*args, **kwargs):
|
60
|
+
try:
|
61
|
+
return func(*args, **kwargs)
|
62
|
+
except Exception as e:
|
63
|
+
_logger.error(f"Error occurred during AutoGen tracing: {e}")
|
64
|
+
|
65
|
+
return wrapper
|
66
|
+
|
67
|
+
|
68
|
+
class MlflowAg2Logger(BaseLogger):
|
69
|
+
def __init__(self):
|
70
|
+
self._chat_state = ChatState()
|
71
|
+
|
72
|
+
def start(self) -> str:
|
73
|
+
return "session_id"
|
74
|
+
|
75
|
+
@_catch_exception
|
76
|
+
def log_new_agent(self, agent: ConversableAgent, init_args: dict[str, Any]) -> None:
|
77
|
+
"""
|
78
|
+
This handler is called whenever a new agent instance is created.
|
79
|
+
Here we patch the agent's methods to start and end a trace around its chat session.
|
80
|
+
"""
|
81
|
+
# TODO: Patch generate_reply() method as well
|
82
|
+
if hasattr(agent, "initiate_chat"):
|
83
|
+
safe_patch(
|
84
|
+
FLAVOR_NAME,
|
85
|
+
agent.__class__,
|
86
|
+
"initiate_chat",
|
87
|
+
# Setting root_only = True because sometimes compounded agent calls initiate_chat()
|
88
|
+
# method of its sub-agents, which should not start a new trace.
|
89
|
+
self._get_patch_function(root_only=True),
|
90
|
+
)
|
91
|
+
if hasattr(agent, "register_function"):
|
92
|
+
|
93
|
+
def patched(original, _self, function_map, **kwargs):
|
94
|
+
original(_self, function_map, **kwargs)
|
95
|
+
# Wrap the newly registered tools to start and end a span around its invocation.
|
96
|
+
for name, f in function_map.items():
|
97
|
+
if f is not None:
|
98
|
+
_self._function_map[name] = functools.partial(
|
99
|
+
self._get_patch_function(span_type=SpanType.TOOL), f
|
100
|
+
)
|
101
|
+
|
102
|
+
safe_patch(FLAVOR_NAME, agent.__class__, "register_function", patched)
|
103
|
+
|
104
|
+
def _get_patch_function(self, span_type: str = SpanType.UNKNOWN, root_only: bool = False):
|
105
|
+
"""
|
106
|
+
Patch a function to start and end a span around its invocation.
|
107
|
+
|
108
|
+
Args:
|
109
|
+
f: The function to patch.
|
110
|
+
span_name: The name of the span. If None, the function name is used.
|
111
|
+
span_type: The type of the span. Default is SpanType.UNKNOWN.
|
112
|
+
root_only: If True, only create a span if it is the root of the chat session.
|
113
|
+
When there is an existing root span for the chat session, the function will
|
114
|
+
not create a new span.
|
115
|
+
"""
|
116
|
+
|
117
|
+
def _wrapper(original, *args, **kwargs):
|
118
|
+
# If autologging is disabled, just run the original function. This is a safety net to
|
119
|
+
# prevent patching side effects from being effective after autologging is disabled.
|
120
|
+
if autologging_is_disabled(FLAVOR_NAME):
|
121
|
+
return original(*args, **kwargs)
|
122
|
+
|
123
|
+
if self._chat_state.session_span is None:
|
124
|
+
# Create the trace per chat session
|
125
|
+
span = start_span_no_context(
|
126
|
+
name=original.__name__,
|
127
|
+
span_type=span_type,
|
128
|
+
inputs=capture_function_input_args(original, args, kwargs),
|
129
|
+
)
|
130
|
+
self._chat_state.session_span = span
|
131
|
+
try:
|
132
|
+
result = original(*args, **kwargs)
|
133
|
+
except Exception as e:
|
134
|
+
result = None
|
135
|
+
self._record_exception(span, e)
|
136
|
+
raise e
|
137
|
+
finally:
|
138
|
+
span.end(outputs=result)
|
139
|
+
# Clear the state to start a new chat session
|
140
|
+
self._chat_state.clear()
|
141
|
+
elif not root_only:
|
142
|
+
span = self._start_span_in_session(
|
143
|
+
name=original.__name__,
|
144
|
+
span_type=span_type,
|
145
|
+
inputs=capture_function_input_args(original, args, kwargs),
|
146
|
+
)
|
147
|
+
try:
|
148
|
+
result = original(*args, **kwargs)
|
149
|
+
except Exception as e:
|
150
|
+
result = None
|
151
|
+
self._record_exception(span, e)
|
152
|
+
raise e
|
153
|
+
finally:
|
154
|
+
span.end(outputs=result)
|
155
|
+
self._chat_state.pending_spans.append(span)
|
156
|
+
else:
|
157
|
+
result = original(*args, **kwargs)
|
158
|
+
return result
|
159
|
+
|
160
|
+
return _wrapper
|
161
|
+
|
162
|
+
def _record_exception(self, span: Span, e: Exception):
|
163
|
+
try:
|
164
|
+
span.set_status(SpanStatus(SpanStatusCode.ERROR, str(e)))
|
165
|
+
span.add_event(SpanEvent.from_exception(e))
|
166
|
+
except Exception as e:
|
167
|
+
_logger.warning(
|
168
|
+
"Failed to record exception in span.", exc_info=_logger.isEnabledFor(logging.DEBUG)
|
169
|
+
)
|
170
|
+
|
171
|
+
def _start_span_in_session(
|
172
|
+
self,
|
173
|
+
name: str,
|
174
|
+
span_type: str,
|
175
|
+
inputs: dict[str, Any],
|
176
|
+
attributes: Optional[dict[str, Any]] = None,
|
177
|
+
start_time_ns: Optional[int] = None,
|
178
|
+
) -> Span:
|
179
|
+
"""
|
180
|
+
Start a span in the current chat session.
|
181
|
+
"""
|
182
|
+
if self._chat_state.session_span is None:
|
183
|
+
_logger.warning("Failed to start span. No active chat session.")
|
184
|
+
return NoOpSpan()
|
185
|
+
|
186
|
+
return start_span_no_context(
|
187
|
+
# Tentatively set the parent ID to the session root span, because we
|
188
|
+
# cannot create a span without a parent span (otherwise it will start
|
189
|
+
# a new trace). The actual parent will be determined once the chat
|
190
|
+
# message is received.
|
191
|
+
parent_span=self._chat_state.session_span,
|
192
|
+
name=name,
|
193
|
+
span_type=span_type,
|
194
|
+
inputs=inputs,
|
195
|
+
attributes=attributes,
|
196
|
+
start_time_ns=start_time_ns,
|
197
|
+
)
|
198
|
+
|
199
|
+
@_catch_exception
|
200
|
+
def log_event(self, source: Union[str, Agent], name: str, **kwargs: dict[str, Any]):
|
201
|
+
event_end_time = time.time_ns()
|
202
|
+
if name == "received_message":
|
203
|
+
if (self._chat_state.last_message is not None) and (
|
204
|
+
kwargs.get("sender") not in _EXCLUDED_MESSAGE_SENDERS
|
205
|
+
):
|
206
|
+
span = self._start_span_in_session(
|
207
|
+
name=kwargs["sender"],
|
208
|
+
# Last message is recorded as the input of the next message
|
209
|
+
inputs=self._chat_state.last_message,
|
210
|
+
span_type=SpanType.AGENT,
|
211
|
+
start_time_ns=self._chat_state.last_message_timestamp,
|
212
|
+
)
|
213
|
+
span.end(outputs=kwargs, end_time_ns=event_end_time)
|
214
|
+
|
215
|
+
# Re-locate the pended spans under this message span
|
216
|
+
for child_span in self._chat_state.pending_spans:
|
217
|
+
child_span._span._parent = span._span.context
|
218
|
+
self._chat_state.pending_spans = []
|
219
|
+
|
220
|
+
self._chat_state.last_message = kwargs
|
221
|
+
self._chat_state.last_message_timestamp = event_end_time
|
222
|
+
|
223
|
+
@_catch_exception
|
224
|
+
def log_chat_completion(
|
225
|
+
self,
|
226
|
+
invocation_id: uuid.UUID,
|
227
|
+
client_id: int,
|
228
|
+
wrapper_id: int,
|
229
|
+
source: Union[str, Agent],
|
230
|
+
request: dict[str, Union[float, str, list[dict[str, str]]]],
|
231
|
+
response: Union[str, ChatCompletion],
|
232
|
+
is_cached: int,
|
233
|
+
cost: float,
|
234
|
+
start_time: str,
|
235
|
+
) -> None:
|
236
|
+
# The start_time passed from AutoGen is in UTC timezone.
|
237
|
+
start_dt = datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S.%f")
|
238
|
+
start_dt = start_dt.replace(tzinfo=timezone.utc)
|
239
|
+
start_time_ns = int(start_dt.timestamp() * 1e9)
|
240
|
+
span = self._start_span_in_session(
|
241
|
+
name="chat_completion",
|
242
|
+
span_type=SpanType.LLM,
|
243
|
+
inputs=request,
|
244
|
+
attributes={
|
245
|
+
"source": source,
|
246
|
+
"client_id": client_id,
|
247
|
+
"invocation_id": invocation_id,
|
248
|
+
"wrapper_id": wrapper_id,
|
249
|
+
"cost": cost,
|
250
|
+
"is_cached": is_cached,
|
251
|
+
},
|
252
|
+
start_time_ns=start_time_ns,
|
253
|
+
)
|
254
|
+
if usage := self._parse_usage(response):
|
255
|
+
span.set_attribute(SpanAttributeKey.CHAT_USAGE, usage)
|
256
|
+
|
257
|
+
span.end(outputs=response, end_time_ns=time.time_ns())
|
258
|
+
self._chat_state.pending_spans.append(span)
|
259
|
+
|
260
|
+
def _parse_usage(self, output: Any) -> Optional[dict[str, int]]:
|
261
|
+
usage = getattr(output, "usage", None)
|
262
|
+
if usage is None:
|
263
|
+
return None
|
264
|
+
input_tokens = usage.prompt_tokens
|
265
|
+
output_tokens = usage.completion_tokens
|
266
|
+
total_tokens = usage.total_tokens
|
267
|
+
if total_tokens is None and None not in (input_tokens, output_tokens):
|
268
|
+
total_tokens = input_tokens + output_tokens
|
269
|
+
return {
|
270
|
+
TokenUsageKey.INPUT_TOKENS: input_tokens,
|
271
|
+
TokenUsageKey.OUTPUT_TOKENS: output_tokens,
|
272
|
+
TokenUsageKey.TOTAL_TOKENS: total_tokens,
|
273
|
+
}
|
274
|
+
|
275
|
+
# The following methods are not used but are required to implement the BaseLogger interface.
|
276
|
+
@_catch_exception
|
277
|
+
def log_function_use(self, *args: Any, **kwargs: Any):
|
278
|
+
pass
|
279
|
+
|
280
|
+
@_catch_exception
|
281
|
+
def log_new_wrapper(self, wrapper, init_args):
|
282
|
+
pass
|
283
|
+
|
284
|
+
@_catch_exception
|
285
|
+
def log_new_client(self, client, wrapper, init_args):
|
286
|
+
pass
|
287
|
+
|
288
|
+
@_catch_exception
|
289
|
+
def stop(self) -> None:
|
290
|
+
pass
|
291
|
+
|
292
|
+
@_catch_exception
|
293
|
+
def get_connection(self):
|
294
|
+
pass
|
@@ -0,0 +1,40 @@
|
|
1
|
+
from mlflow.anthropic.autolog import async_patched_class_call, patched_class_call
|
2
|
+
from mlflow.utils.annotations import experimental
|
3
|
+
from mlflow.utils.autologging_utils import autologging_integration, safe_patch
|
4
|
+
|
5
|
+
FLAVOR_NAME = "anthropic"
|
6
|
+
|
7
|
+
|
8
|
+
@experimental(version="2.19.0")
|
9
|
+
@autologging_integration(FLAVOR_NAME)
|
10
|
+
def autolog(
|
11
|
+
log_traces: bool = True,
|
12
|
+
disable: bool = False,
|
13
|
+
silent: bool = False,
|
14
|
+
):
|
15
|
+
"""
|
16
|
+
Enables (or disables) and configures autologging from Anthropic to MLflow.
|
17
|
+
Only synchronous calls and asynchronous APIs are supported. Streaming is not recorded.
|
18
|
+
|
19
|
+
Args:
|
20
|
+
log_traces: If ``True``, traces are logged for Anthropic models.
|
21
|
+
If ``False``, no traces are collected during inference. Default to ``True``.
|
22
|
+
disable: If ``True``, disables the Anthropic autologging. Default to ``False``.
|
23
|
+
silent: If ``True``, suppress all event logs and warnings from MLflow during Anthropic
|
24
|
+
autologging. If ``False``, show all events and warnings.
|
25
|
+
"""
|
26
|
+
from anthropic.resources import AsyncMessages, Messages
|
27
|
+
|
28
|
+
safe_patch(
|
29
|
+
FLAVOR_NAME,
|
30
|
+
Messages,
|
31
|
+
"create",
|
32
|
+
patched_class_call,
|
33
|
+
)
|
34
|
+
|
35
|
+
safe_patch(
|
36
|
+
FLAVOR_NAME,
|
37
|
+
AsyncMessages,
|
38
|
+
"create",
|
39
|
+
async_patched_class_call,
|
40
|
+
)
|
@@ -0,0 +1,129 @@
|
|
1
|
+
import logging
|
2
|
+
from typing import Any, Optional
|
3
|
+
|
4
|
+
import mlflow
|
5
|
+
import mlflow.anthropic
|
6
|
+
from mlflow.anthropic.chat import convert_message_to_mlflow_chat, convert_tool_to_mlflow_chat_tool
|
7
|
+
from mlflow.entities import SpanType
|
8
|
+
from mlflow.entities.span import LiveSpan
|
9
|
+
from mlflow.entities.span_event import SpanEvent
|
10
|
+
from mlflow.entities.span_status import SpanStatusCode
|
11
|
+
from mlflow.tracing.constant import SpanAttributeKey, TokenUsageKey
|
12
|
+
from mlflow.tracing.fluent import start_span_no_context
|
13
|
+
from mlflow.tracing.utils import (
|
14
|
+
construct_full_inputs,
|
15
|
+
set_span_chat_messages,
|
16
|
+
set_span_chat_tools,
|
17
|
+
)
|
18
|
+
from mlflow.utils.autologging_utils.config import AutoLoggingConfig
|
19
|
+
|
20
|
+
_logger = logging.getLogger(__name__)
|
21
|
+
|
22
|
+
|
23
|
+
def patched_class_call(original, self, *args, **kwargs):
|
24
|
+
with TracingSession(original, self, args, kwargs) as manager:
|
25
|
+
output = original(self, *args, **kwargs)
|
26
|
+
manager.output = output
|
27
|
+
return output
|
28
|
+
|
29
|
+
|
30
|
+
async def async_patched_class_call(original, self, *args, **kwargs):
|
31
|
+
async with TracingSession(original, self, args, kwargs) as manager:
|
32
|
+
output = await original(self, *args, **kwargs)
|
33
|
+
manager.output = output
|
34
|
+
return output
|
35
|
+
|
36
|
+
|
37
|
+
class TracingSession:
|
38
|
+
"""Context manager for handling MLflow spans in both sync and async contexts."""
|
39
|
+
|
40
|
+
def __init__(self, original, instance, args, kwargs):
|
41
|
+
self.original = original
|
42
|
+
self.instance = instance
|
43
|
+
self.inputs = construct_full_inputs(original, instance, *args, **kwargs)
|
44
|
+
|
45
|
+
# These attributes are set outside the constructor.
|
46
|
+
self.span = None
|
47
|
+
self.output = None
|
48
|
+
|
49
|
+
def __enter__(self):
|
50
|
+
return self._enter_impl()
|
51
|
+
|
52
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
53
|
+
self._exit_impl(exc_type, exc_val, exc_tb)
|
54
|
+
|
55
|
+
async def __aenter__(self):
|
56
|
+
return self._enter_impl()
|
57
|
+
|
58
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
59
|
+
self._exit_impl(exc_type, exc_val, exc_tb)
|
60
|
+
|
61
|
+
def _enter_impl(self):
|
62
|
+
config = AutoLoggingConfig.init(flavor_name=mlflow.anthropic.FLAVOR_NAME)
|
63
|
+
|
64
|
+
if config.log_traces:
|
65
|
+
attributes = {}
|
66
|
+
self.span = start_span_no_context(
|
67
|
+
name=f"{self.instance.__class__.__name__}.{self.original.__name__}",
|
68
|
+
span_type=_get_span_type(self.original.__name__),
|
69
|
+
inputs=self.inputs,
|
70
|
+
attributes=attributes,
|
71
|
+
)
|
72
|
+
_set_tool_attribute(self.span, self.inputs)
|
73
|
+
|
74
|
+
return self
|
75
|
+
|
76
|
+
def _exit_impl(self, exc_type, exc_val, exc_tb) -> None:
|
77
|
+
if self.span:
|
78
|
+
if exc_val:
|
79
|
+
self.span.add_event(SpanEvent.from_exception(exc_val))
|
80
|
+
status = SpanStatusCode.ERROR
|
81
|
+
else:
|
82
|
+
status = SpanStatusCode.OK
|
83
|
+
|
84
|
+
_set_chat_message_attribute(self.span, self.inputs, self.output)
|
85
|
+
self.span.end(status=status, outputs=self.output)
|
86
|
+
|
87
|
+
|
88
|
+
def _get_span_type(task_name: str) -> str:
|
89
|
+
# Anthropic has a few APIs in beta, e.g., count_tokens.
|
90
|
+
# Once they are stable, we can add them to the mapping.
|
91
|
+
span_type_mapping = {
|
92
|
+
"create": SpanType.CHAT_MODEL,
|
93
|
+
}
|
94
|
+
return span_type_mapping.get(task_name, SpanType.UNKNOWN)
|
95
|
+
|
96
|
+
|
97
|
+
def _set_tool_attribute(span: LiveSpan, inputs: dict[str, Any]):
|
98
|
+
if (tools := inputs.get("tools")) is not None:
|
99
|
+
try:
|
100
|
+
tools = [convert_tool_to_mlflow_chat_tool(tool) for tool in tools]
|
101
|
+
set_span_chat_tools(span, tools)
|
102
|
+
except Exception as e:
|
103
|
+
_logger.debug(f"Failed to set tools for {span}. Error: {e}")
|
104
|
+
|
105
|
+
|
106
|
+
def _set_chat_message_attribute(span: LiveSpan, inputs: dict[str, Any], output: Any):
|
107
|
+
try:
|
108
|
+
messages = [convert_message_to_mlflow_chat(msg) for msg in inputs.get("messages", [])]
|
109
|
+
if output is not None:
|
110
|
+
messages.append(convert_message_to_mlflow_chat(output))
|
111
|
+
set_span_chat_messages(span, messages)
|
112
|
+
if usage := _parse_usage(output):
|
113
|
+
span.set_attribute(SpanAttributeKey.CHAT_USAGE, usage)
|
114
|
+
except Exception as e:
|
115
|
+
_logger.debug(f"Failed to set chat messages for {span}. Error: {e}")
|
116
|
+
|
117
|
+
|
118
|
+
def _parse_usage(output: Any) -> Optional[dict[str, int]]:
|
119
|
+
try:
|
120
|
+
usage = getattr(output, "usage", None)
|
121
|
+
if usage:
|
122
|
+
return {
|
123
|
+
TokenUsageKey.INPUT_TOKENS: usage.input_tokens,
|
124
|
+
TokenUsageKey.OUTPUT_TOKENS: usage.output_tokens,
|
125
|
+
TokenUsageKey.TOTAL_TOKENS: usage.input_tokens + usage.output_tokens,
|
126
|
+
}
|
127
|
+
except Exception as e:
|
128
|
+
_logger.debug(f"Failed to parse token usage from output: {e}")
|
129
|
+
return None
|
mlflow/anthropic/chat.py
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
import json
|
2
|
+
from typing import Any, Union
|
3
|
+
|
4
|
+
from pydantic import BaseModel
|
5
|
+
|
6
|
+
from mlflow.exceptions import MlflowException
|
7
|
+
from mlflow.types.chat import (
|
8
|
+
ChatMessage,
|
9
|
+
ChatTool,
|
10
|
+
Function,
|
11
|
+
FunctionToolDefinition,
|
12
|
+
ImageContentPart,
|
13
|
+
ImageUrl,
|
14
|
+
TextContentPart,
|
15
|
+
ToolCall,
|
16
|
+
)
|
17
|
+
from mlflow.utils import IS_PYDANTIC_V2_OR_NEWER
|
18
|
+
|
19
|
+
|
20
|
+
def convert_message_to_mlflow_chat(message: Union[BaseModel, dict[str, Any]]) -> ChatMessage:
|
21
|
+
"""
|
22
|
+
Convert Anthropic message object into MLflow's standard format (OpenAI compatible).
|
23
|
+
|
24
|
+
Ref: https://docs.anthropic.com/en/api/messages#body-messages
|
25
|
+
|
26
|
+
Args:
|
27
|
+
message: Anthropic message object or a dictionary representing the message.
|
28
|
+
|
29
|
+
Returns:
|
30
|
+
ChatMessage: MLflow's standard chat message object.
|
31
|
+
"""
|
32
|
+
if isinstance(message, dict):
|
33
|
+
content = message.get("content")
|
34
|
+
role = message.get("role")
|
35
|
+
elif isinstance(message, BaseModel):
|
36
|
+
content = message.content
|
37
|
+
role = message.role
|
38
|
+
else:
|
39
|
+
raise MlflowException.invalid_parameter_value(
|
40
|
+
f"Message must be either a dict or a Message object, but got: {type(message)}."
|
41
|
+
)
|
42
|
+
|
43
|
+
if isinstance(content, str):
|
44
|
+
return ChatMessage(role=role, content=content)
|
45
|
+
|
46
|
+
elif isinstance(content, list):
|
47
|
+
contents = []
|
48
|
+
tool_calls = []
|
49
|
+
tool_call_id = None
|
50
|
+
for content_block in content:
|
51
|
+
if isinstance(content_block, BaseModel):
|
52
|
+
if IS_PYDANTIC_V2_OR_NEWER:
|
53
|
+
content_block = content_block.model_dump()
|
54
|
+
else:
|
55
|
+
content_block = content_block.dict()
|
56
|
+
|
57
|
+
content_type = content_block.get("type")
|
58
|
+
if content_type == "tool_use":
|
59
|
+
# Anthropic response contains tool calls in the content block
|
60
|
+
# Ref: https://docs.anthropic.com/en/docs/build-with-claude/tool-use#example-api-response-with-a-tool-use-content-block
|
61
|
+
tool_calls.append(
|
62
|
+
ToolCall(
|
63
|
+
id=content_block["id"],
|
64
|
+
function=Function(
|
65
|
+
name=content_block["name"], arguments=json.dumps(content_block["input"])
|
66
|
+
),
|
67
|
+
type="function",
|
68
|
+
)
|
69
|
+
)
|
70
|
+
elif content_type == "tool_result":
|
71
|
+
# In Anthropic, the result of tool execution is returned as a special content type
|
72
|
+
# "tool_result" with "user" role, which corresponds to the "tool" role in OpenAI.
|
73
|
+
role = "tool"
|
74
|
+
tool_call_id = content_block["tool_use_id"]
|
75
|
+
if result_content := content_block.get("content"):
|
76
|
+
contents.append(_parse_content(result_content))
|
77
|
+
else:
|
78
|
+
contents.append(TextContentPart(text="", type="text"))
|
79
|
+
else:
|
80
|
+
contents.append(_parse_content(content_block))
|
81
|
+
|
82
|
+
message = ChatMessage(role=role, content=contents)
|
83
|
+
# Only set tool_calls field when it is present
|
84
|
+
if tool_calls:
|
85
|
+
message.tool_calls = tool_calls
|
86
|
+
if tool_call_id:
|
87
|
+
message.tool_call_id = tool_call_id
|
88
|
+
return message
|
89
|
+
|
90
|
+
else:
|
91
|
+
raise MlflowException.invalid_parameter_value(
|
92
|
+
f"Invalid content type. Must be either a string or a list, but got: {type(content)}."
|
93
|
+
)
|
94
|
+
|
95
|
+
|
96
|
+
def _parse_content(content: Union[str, dict[str, Any]]) -> Union[TextContentPart, ImageContentPart]:
|
97
|
+
if isinstance(content, str):
|
98
|
+
return TextContentPart(text=content, type="text")
|
99
|
+
|
100
|
+
content_type = content.get("type")
|
101
|
+
if content_type == "text":
|
102
|
+
return TextContentPart(text=content["text"], type="text")
|
103
|
+
elif content_type == "image":
|
104
|
+
source = content["source"]
|
105
|
+
return ImageContentPart(
|
106
|
+
image_url=ImageUrl(
|
107
|
+
url=f"data:{source['media_type']};{source['type']},{source['data']}"
|
108
|
+
),
|
109
|
+
type="image_url",
|
110
|
+
)
|
111
|
+
# Claude 3.7 added new "thinking" content block, which is essentially a text block as of now.
|
112
|
+
# TODO: We should consider adding a new ContentPart type if more providers support this.
|
113
|
+
# https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking
|
114
|
+
elif content_type == "thinking":
|
115
|
+
return TextContentPart(text=content["thinking"], type="text")
|
116
|
+
else:
|
117
|
+
raise MlflowException.invalid_parameter_value(
|
118
|
+
f"Unknown content type: {content_type['type']}. Please make sure the message "
|
119
|
+
"is a valid Anthropic message object. If it is a valid type, contact to the "
|
120
|
+
"MLflow maintainer via https://github.com/mlflow/mlflow/issues/new/choose for "
|
121
|
+
"requesting support for a new message type."
|
122
|
+
)
|
123
|
+
|
124
|
+
|
125
|
+
def convert_tool_to_mlflow_chat_tool(tool: dict[str, Any]) -> ChatTool:
|
126
|
+
"""
|
127
|
+
Convert Anthropic tool definition into MLflow's standard format (OpenAI compatible).
|
128
|
+
|
129
|
+
Ref: https://docs.anthropic.com/en/docs/build-with-claude/tool-use
|
130
|
+
|
131
|
+
Args:
|
132
|
+
tool: A dictionary represents a single tool definition in the input request.
|
133
|
+
|
134
|
+
Returns:
|
135
|
+
ChatTool: MLflow's standard tool definition object.
|
136
|
+
"""
|
137
|
+
return ChatTool(
|
138
|
+
type="function",
|
139
|
+
function=FunctionToolDefinition(
|
140
|
+
name=tool.get("name"),
|
141
|
+
description=tool.get("description"),
|
142
|
+
parameters=tool.get("input_schema"),
|
143
|
+
),
|
144
|
+
)
|