arize-phoenix 5.10.0__tar.gz → 5.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of arize-phoenix might be problematic. Click here for more details.
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/PKG-INFO +2 -1
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/pyproject.toml +1 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/config.py +13 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/facilitator.py +3 -2
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/playground_clients.py +29 -13
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/playground_spans.py +6 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/chat_mutations.py +75 -34
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/subscriptions.py +108 -49
- arize_phoenix-5.11.0/src/phoenix/server/static/.vite/manifest.json +78 -0
- arize_phoenix-5.10.0/src/phoenix/server/static/assets/components-BXIz9ZO8.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/components-C_HASv83.js +90 -90
- arize_phoenix-5.10.0/src/phoenix/server/static/assets/index-DTut7g1y.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/index-D7UiCRtr.js +2 -2
- arize_phoenix-5.10.0/src/phoenix/server/static/assets/pages-B8FpJuXu.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/pages-DYHcAdjT.js +313 -264
- arize_phoenix-5.10.0/src/phoenix/server/static/assets/vendor-BX8_Znqy.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/vendor-BCxsh5i3.js +150 -150
- arize_phoenix-5.10.0/src/phoenix/server/static/assets/vendor-arizeai-CtHir-Ua.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/vendor-arizeai-C2CDZgMz.js +28 -28
- arize_phoenix-5.10.0/src/phoenix/server/static/assets/vendor-codemirror-DLlGiguX.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/vendor-codemirror-DYbtnCTn.js +1 -1
- arize_phoenix-5.10.0/src/phoenix/server/static/assets/vendor-recharts-CJRple0d.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/vendor-recharts-P6W8G0Mb.js +1 -1
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/span_evaluations.py +4 -3
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/utilities/json.py +7 -1
- arize_phoenix-5.11.0/src/phoenix/version.py +1 -0
- arize_phoenix-5.10.0/src/phoenix/server/static/.vite/manifest.json +0 -78
- arize_phoenix-5.10.0/src/phoenix/version.py +0 -1
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/.gitignore +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/IP_NOTICE +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/LICENSE +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/README.md +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/auth.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/core/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/core/embedding_dimension.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/core/model.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/core/model_schema.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/core/model_schema_adapter.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/datetime_utils.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/README.md +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/alembic.ini +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/bulk_inserter.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/engines.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/enums.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/helpers.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/constants.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/dataset.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/document_annotation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/evaluation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/helpers.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/span.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/span_annotation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/trace_annotation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/types.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/migrate.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/env.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/script.py.mako +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/versions/3be8647b87d8_add_token_columns_to_spans_table.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/versions/cd164e83824f_users_and_tokens.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/versions/cf03bd6bae1d_init.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/db/models.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/exceptions.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/experiments/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/experiments/evaluators/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/experiments/evaluators/base.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/experiments/evaluators/code_evaluators.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/experiments/evaluators/llm_evaluators.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/experiments/evaluators/utils.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/experiments/functions.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/experiments/tracing.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/experiments/types.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/experiments/utils.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/inferences/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/inferences/errors.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/inferences/fixtures.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/inferences/inferences.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/inferences/schema.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/inferences/validation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/logging/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/logging/_config.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/logging/_filter.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/logging/_formatter.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/metrics/README.md +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/metrics/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/metrics/binning.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/metrics/metrics.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/metrics/mixins.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/metrics/retrieval_metrics.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/metrics/timeseries.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/metrics/wrappers.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/pointcloud/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/pointcloud/clustering.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/pointcloud/pointcloud.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/pointcloud/projectors.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/pointcloud/umap_parameters.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/py.typed +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/README.md +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/auth.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/context.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/annotation_summaries.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/average_experiment_run_latency.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/cache/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/cache/two_tier_cache.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/dataset_example_spans.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/document_evaluation_summaries.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/document_evaluations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/document_retrieval_metrics.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/experiment_annotation_summaries.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/experiment_error_rates.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/experiment_run_annotations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/experiment_run_counts.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/experiment_sequence_number.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/latency_ms_quantile.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/min_start_or_max_end_times.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/project_by_name.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/record_counts.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/span_annotations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/span_dataset_examples.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/span_descendants.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/span_projects.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/token_counts.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/trace_row_ids.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/user_roles.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/users.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/exceptions.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/dataset_helpers.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/playground_registry.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/ChatCompletionInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/ChatCompletionMessageInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/ClearProjectInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/CreateDatasetInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/CreateSpanAnnotationInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/CreateTraceAnnotationInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DatasetExampleInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DatasetSort.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DatasetVersionSort.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DeleteAnnotationsInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DeleteDatasetInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/GenerativeModelInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/Granularity.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/InvocationParameters.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/PatchAnnotationInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/PatchDatasetInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/SpanAnnotationSort.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/SpanSort.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/TemplateOptions.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/TraceAnnotationSort.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/UserRoleInput.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/interceptor.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/api_key_mutations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/dataset_mutations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/experiment_mutations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/export_events_mutations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/project_mutations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/span_annotations_mutations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/trace_annotations_mutations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/user_mutations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/openapi/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/openapi/main.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/openapi/schema.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/queries.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/auth.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/embeddings.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/oauth2.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/utils.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/datasets.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/evaluations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/experiment_evaluations.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/experiment_runs.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/experiments.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/pydantic_compat.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/spans.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/traces.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/utils.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/schema.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Annotation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/AnnotationSummary.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/AnnotatorKind.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ApiKey.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/AuthMethod.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ChatCompletionMessageRole.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ChatCompletionSubscriptionPayload.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Cluster.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/CreateDatasetPayload.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Dataset.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DatasetExample.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DatasetExampleRevision.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DatasetValues.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DatasetVersion.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Dimension.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DimensionShape.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DimensionType.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DocumentEvaluationSummary.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DocumentRetrievalMetrics.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Evaluation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/EvaluationSummary.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Event.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/EventMetadata.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExampleRevisionInterface.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Experiment.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExperimentComparison.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExperimentRun.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExperimentRunAnnotation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExportedFile.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Functionality.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/GenerativeModel.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/GenerativeProvider.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Inferences.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/InferencesRole.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/LabelFraction.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/MimeType.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Model.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/NumericRange.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/PerformanceMetric.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Project.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/PromptResponse.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Retrieval.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Segments.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/SortDir.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Span.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/SpanAnnotation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/SystemApiKey.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/TemplateLanguage.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/TimeSeries.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Trace.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/TraceAnnotation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/User.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/UserApiKey.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/UserRole.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ValidationResult.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/node.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/pagination.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/utils.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/app.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/bearer_auth.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/dml_event.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/dml_event_handler.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/email/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/email/sender.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/email/templates/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/email/templates/password_reset.html +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/email/types.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/grpc_server.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/jwt_store.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/main.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/oauth2.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/openapi/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/prometheus.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/rate_limiters.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon.png +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/assets/vendor-DxkFTwjz.css +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/assets/vendor-three-DwGkEfCM.js +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/favicon.ico +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/static/modernizr.js +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/telemetry.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/templates/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/templates/index.html +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/thread_server.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/types.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/services.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/session/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/session/client.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/session/data_extractor.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/session/evaluation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/session/session.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/settings.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/attributes.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/dsl/README.md +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/dsl/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/dsl/filter.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/dsl/helpers.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/dsl/query.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/errors.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/evaluation_conventions.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/exporter.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/fixtures.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/otel.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/projects.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/schemas.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/span_json_decoder.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/span_json_encoder.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/trace_dataset.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/utils.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/v1/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/v1/evaluation_pb2.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/trace/v1/evaluation_pb2.pyi +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/utilities/__init__.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/utilities/client.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/utilities/deprecation.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/utilities/error_handling.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/utilities/logging.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/utilities/project.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/utilities/re.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/utilities/span_store.py +0 -0
- {arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/utilities/template_formatters.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: arize-phoenix
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.11.0
|
|
4
4
|
Summary: AI Observability and Evaluation
|
|
5
5
|
Project-URL: Documentation, https://docs.arize.com/phoenix/
|
|
6
6
|
Project-URL: Issues, https://github.com/Arize-ai/phoenix/issues
|
|
@@ -53,6 +53,7 @@ Requires-Dist: wrapt
|
|
|
53
53
|
Provides-Extra: container
|
|
54
54
|
Requires-Dist: anthropic; extra == 'container'
|
|
55
55
|
Requires-Dist: fast-hdbscan>=0.2.0; extra == 'container'
|
|
56
|
+
Requires-Dist: google-generativeai; extra == 'container'
|
|
56
57
|
Requires-Dist: numba>=0.60.0; extra == 'container'
|
|
57
58
|
Requires-Dist: openai>=1.0.0; extra == 'container'
|
|
58
59
|
Requires-Dist: opentelemetry-exporter-otlp; extra == 'container'
|
|
@@ -97,6 +97,13 @@ ENV_PHOENIX_SERVER_INSTRUMENTATION_OTLP_TRACE_COLLECTOR_GRPC_ENDPOINT = (
|
|
|
97
97
|
ENV_PHOENIX_ENABLE_AUTH = "PHOENIX_ENABLE_AUTH"
|
|
98
98
|
ENV_PHOENIX_DISABLE_RATE_LIMIT = "PHOENIX_DISABLE_RATE_LIMIT"
|
|
99
99
|
ENV_PHOENIX_SECRET = "PHOENIX_SECRET"
|
|
100
|
+
ENV_PHOENIX_DEFAULT_ADMIN_INITIAL_PASSWORD = "PHOENIX_DEFAULT_ADMIN_INITIAL_PASSWORD"
|
|
101
|
+
"""
|
|
102
|
+
The initial password for the default admin account, which defaults to ‘admin’ if not
|
|
103
|
+
explicitly set. Note that changing this value will have no effect if the default admin
|
|
104
|
+
record already exists in the database. In such cases, the default admin password must
|
|
105
|
+
be updated manually in the application.
|
|
106
|
+
"""
|
|
100
107
|
ENV_PHOENIX_API_KEY = "PHOENIX_API_KEY"
|
|
101
108
|
ENV_PHOENIX_USE_SECURE_COOKIES = "PHOENIX_USE_SECURE_COOKIES"
|
|
102
109
|
ENV_PHOENIX_ACCESS_TOKEN_EXPIRY_MINUTES = "PHOENIX_ACCESS_TOKEN_EXPIRY_MINUTES"
|
|
@@ -274,6 +281,12 @@ def get_env_phoenix_secret() -> Optional[str]:
|
|
|
274
281
|
return phoenix_secret
|
|
275
282
|
|
|
276
283
|
|
|
284
|
+
def get_env_default_admin_initial_password() -> str:
|
|
285
|
+
from phoenix.auth import DEFAULT_ADMIN_PASSWORD
|
|
286
|
+
|
|
287
|
+
return os.environ.get(ENV_PHOENIX_DEFAULT_ADMIN_INITIAL_PASSWORD) or DEFAULT_ADMIN_PASSWORD
|
|
288
|
+
|
|
289
|
+
|
|
277
290
|
def get_env_phoenix_use_secure_cookies() -> bool:
|
|
278
291
|
return _bool_val(ENV_PHOENIX_USE_SECURE_COOKIES, False)
|
|
279
292
|
|
|
@@ -13,13 +13,13 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
13
13
|
|
|
14
14
|
from phoenix.auth import (
|
|
15
15
|
DEFAULT_ADMIN_EMAIL,
|
|
16
|
-
DEFAULT_ADMIN_PASSWORD,
|
|
17
16
|
DEFAULT_ADMIN_USERNAME,
|
|
18
17
|
DEFAULT_SECRET_LENGTH,
|
|
19
18
|
DEFAULT_SYSTEM_EMAIL,
|
|
20
19
|
DEFAULT_SYSTEM_USERNAME,
|
|
21
20
|
compute_password_hash,
|
|
22
21
|
)
|
|
22
|
+
from phoenix.config import get_env_default_admin_initial_password
|
|
23
23
|
from phoenix.db import models
|
|
24
24
|
from phoenix.db.enums import COLUMN_ENUMS, UserRole
|
|
25
25
|
from phoenix.server.types import DbSessionFactory
|
|
@@ -97,7 +97,8 @@ async def _ensure_user_roles(session: AsyncSession) -> None:
|
|
|
97
97
|
admin_role_id := role_ids.get(admin_role)
|
|
98
98
|
) is not None:
|
|
99
99
|
salt = secrets.token_bytes(DEFAULT_SECRET_LENGTH)
|
|
100
|
-
|
|
100
|
+
password = get_env_default_admin_initial_password()
|
|
101
|
+
compute = partial(compute_password_hash, password=password, salt=salt)
|
|
101
102
|
loop = asyncio.get_running_loop()
|
|
102
103
|
hash_ = await loop.run_in_executor(None, compute)
|
|
103
104
|
admin_user = models.User(
|
{arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/playground_clients.py
RENAMED
|
@@ -2,6 +2,7 @@ import asyncio
|
|
|
2
2
|
import importlib.util
|
|
3
3
|
import inspect
|
|
4
4
|
import json
|
|
5
|
+
import os
|
|
5
6
|
import time
|
|
6
7
|
from abc import ABC, abstractmethod
|
|
7
8
|
from collections.abc import AsyncIterator, Callable, Iterator
|
|
@@ -25,6 +26,7 @@ from phoenix.evals.models.rate_limiters import (
|
|
|
25
26
|
RateLimiter,
|
|
26
27
|
RateLimitError,
|
|
27
28
|
)
|
|
29
|
+
from phoenix.server.api.exceptions import BadRequest
|
|
28
30
|
from phoenix.server.api.helpers.playground_registry import PROVIDER_DEFAULT, register_llm_client
|
|
29
31
|
from phoenix.server.api.input_types.GenerativeModelInput import GenerativeModelInput
|
|
30
32
|
from phoenix.server.api.input_types.InvocationParameters import (
|
|
@@ -99,9 +101,9 @@ class PlaygroundRateLimiter(RateLimiter, KeyedSingleton):
|
|
|
99
101
|
super().__init__(
|
|
100
102
|
rate_limit_error=rate_limit_error,
|
|
101
103
|
max_rate_limit_retries=3,
|
|
102
|
-
initial_per_second_request_rate=
|
|
103
|
-
maximum_per_second_request_rate=
|
|
104
|
-
enforcement_window_minutes=
|
|
104
|
+
initial_per_second_request_rate=1.0,
|
|
105
|
+
maximum_per_second_request_rate=3.0,
|
|
106
|
+
enforcement_window_minutes=0.05,
|
|
105
107
|
rate_reduction_factor=0.5,
|
|
106
108
|
rate_increase_factor=0.01,
|
|
107
109
|
cooldown_seconds=5,
|
|
@@ -128,10 +130,11 @@ class PlaygroundRateLimiter(RateLimiter, KeyedSingleton):
|
|
|
128
130
|
self._rate_limit_handling.set() # Set the event as a failsafe
|
|
129
131
|
await self._throttler.async_wait_until_ready()
|
|
130
132
|
request_start_time = time.time()
|
|
131
|
-
|
|
132
|
-
|
|
133
|
+
maybe_coroutine = fn(*args, **kwargs)
|
|
134
|
+
if inspect.iscoroutine(maybe_coroutine):
|
|
135
|
+
return await maybe_coroutine # type: ignore
|
|
133
136
|
else:
|
|
134
|
-
return
|
|
137
|
+
return maybe_coroutine
|
|
135
138
|
except self._rate_limit_error:
|
|
136
139
|
async with self._rate_limit_handling_lock:
|
|
137
140
|
self._rate_limit_handling.clear() # prevent new requests from starting
|
|
@@ -258,6 +261,10 @@ class OpenAIStreamingClient(PlaygroundStreamingClient):
|
|
|
258
261
|
from openai import AsyncOpenAI
|
|
259
262
|
from openai import RateLimitError as OpenAIRateLimitError
|
|
260
263
|
|
|
264
|
+
# todo: check if custom base url is set before raising error to allow
|
|
265
|
+
# for custom endpoints that don't require an API key
|
|
266
|
+
if not (api_key := api_key or os.environ.get("OPENAI_API_KEY")):
|
|
267
|
+
raise BadRequest("An API key is required for OpenAI models")
|
|
261
268
|
super().__init__(model=model, api_key=api_key)
|
|
262
269
|
self._attributes[LLM_PROVIDER] = OpenInferenceLLMProviderValues.OPENAI.value
|
|
263
270
|
self._attributes[LLM_SYSTEM] = OpenInferenceLLMSystemValues.OPENAI.value
|
|
@@ -341,7 +348,7 @@ class OpenAIStreamingClient(PlaygroundStreamingClient):
|
|
|
341
348
|
openai_messages = [self.to_openai_chat_completion_param(*message) for message in messages]
|
|
342
349
|
tool_call_ids: dict[int, str] = {}
|
|
343
350
|
token_usage: Optional["CompletionUsage"] = None
|
|
344
|
-
throttled_create = self.rate_limiter.
|
|
351
|
+
throttled_create = self.rate_limiter._alimit(self.client.chat.completions.create)
|
|
345
352
|
async for chunk in await throttled_create(
|
|
346
353
|
messages=openai_messages,
|
|
347
354
|
model=self.model_name,
|
|
@@ -510,7 +517,7 @@ class OpenAIO1StreamingClient(OpenAIStreamingClient):
|
|
|
510
517
|
|
|
511
518
|
tool_call_ids: dict[int, str] = {}
|
|
512
519
|
|
|
513
|
-
throttled_create = self.rate_limiter.
|
|
520
|
+
throttled_create = self.rate_limiter._alimit(self.client.chat.completions.create)
|
|
514
521
|
response = await throttled_create(
|
|
515
522
|
messages=openai_messages,
|
|
516
523
|
model=self.model_name,
|
|
@@ -618,12 +625,14 @@ class AzureOpenAIStreamingClient(OpenAIStreamingClient):
|
|
|
618
625
|
super().__init__(model=model, api_key=api_key)
|
|
619
626
|
self._attributes[LLM_PROVIDER] = OpenInferenceLLMProviderValues.AZURE.value
|
|
620
627
|
self._attributes[LLM_SYSTEM] = OpenInferenceLLMSystemValues.OPENAI.value
|
|
621
|
-
if model.endpoint
|
|
622
|
-
raise
|
|
628
|
+
if not (endpoint := model.endpoint or os.environ.get("AZURE_OPENAI_ENDPOINT")):
|
|
629
|
+
raise BadRequest("An Azure endpoint is required for Azure OpenAI models")
|
|
630
|
+
if not (api_version := model.api_version or os.environ.get("OPENAI_API_VERSION")):
|
|
631
|
+
raise BadRequest("An OpenAI API version is required for Azure OpenAI models")
|
|
623
632
|
self.client = AsyncAzureOpenAI(
|
|
624
633
|
api_key=api_key,
|
|
625
|
-
azure_endpoint=
|
|
626
|
-
api_version=
|
|
634
|
+
azure_endpoint=endpoint,
|
|
635
|
+
api_version=api_version,
|
|
627
636
|
)
|
|
628
637
|
|
|
629
638
|
|
|
@@ -648,6 +657,8 @@ class AnthropicStreamingClient(PlaygroundStreamingClient):
|
|
|
648
657
|
super().__init__(model=model, api_key=api_key)
|
|
649
658
|
self._attributes[LLM_PROVIDER] = OpenInferenceLLMProviderValues.ANTHROPIC.value
|
|
650
659
|
self._attributes[LLM_SYSTEM] = OpenInferenceLLMSystemValues.ANTHROPIC.value
|
|
660
|
+
if not (api_key := api_key or os.environ.get("ANTHROPIC_API_KEY")):
|
|
661
|
+
raise BadRequest("An API key is required for Anthropic models")
|
|
651
662
|
self.client = anthropic.AsyncAnthropic(api_key=api_key)
|
|
652
663
|
self.model_name = model.name
|
|
653
664
|
self.rate_limiter = PlaygroundRateLimiter(model.provider_key, anthropic.RateLimitError)
|
|
@@ -707,7 +718,6 @@ class AnthropicStreamingClient(PlaygroundStreamingClient):
|
|
|
707
718
|
"messages": anthropic_messages,
|
|
708
719
|
"model": self.model_name,
|
|
709
720
|
"system": system_prompt,
|
|
710
|
-
"max_tokens": 1024,
|
|
711
721
|
"tools": tools,
|
|
712
722
|
**invocation_parameters,
|
|
713
723
|
}
|
|
@@ -820,6 +830,12 @@ class GeminiStreamingClient(PlaygroundStreamingClient):
|
|
|
820
830
|
super().__init__(model=model, api_key=api_key)
|
|
821
831
|
self._attributes[LLM_PROVIDER] = OpenInferenceLLMProviderValues.GOOGLE.value
|
|
822
832
|
self._attributes[LLM_SYSTEM] = OpenInferenceLLMSystemValues.VERTEXAI.value
|
|
833
|
+
if not (
|
|
834
|
+
api_key := api_key
|
|
835
|
+
or os.environ.get("GEMINI_API_KEY")
|
|
836
|
+
or os.environ.get("GOOGLE_API_KEY")
|
|
837
|
+
):
|
|
838
|
+
raise BadRequest("An API key is required for Gemini models")
|
|
823
839
|
google_genai.configure(api_key=api_key)
|
|
824
840
|
self.model_name = model.name
|
|
825
841
|
|
{arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/playground_spans.py
RENAMED
|
@@ -379,6 +379,11 @@ def _llm_output_messages(
|
|
|
379
379
|
if content := "".join(chunk.content for chunk in text_chunks):
|
|
380
380
|
yield f"{LLM_OUTPUT_MESSAGES}.0.{MESSAGE_CONTENT}", content
|
|
381
381
|
for tool_call_index, (_tool_call_id, tool_call_chunks_) in enumerate(tool_call_chunks.items()):
|
|
382
|
+
if _tool_call_id:
|
|
383
|
+
yield (
|
|
384
|
+
f"{LLM_OUTPUT_MESSAGES}.0.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_ID}",
|
|
385
|
+
_tool_call_id,
|
|
386
|
+
)
|
|
382
387
|
if tool_call_chunks_ and (name := tool_call_chunks_[0].function.name):
|
|
383
388
|
yield (
|
|
384
389
|
f"{LLM_OUTPUT_MESSAGES}.0.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_FUNCTION_NAME}",
|
|
@@ -441,6 +446,7 @@ MESSAGE_CONTENT = MessageAttributes.MESSAGE_CONTENT
|
|
|
441
446
|
MESSAGE_ROLE = MessageAttributes.MESSAGE_ROLE
|
|
442
447
|
MESSAGE_TOOL_CALLS = MessageAttributes.MESSAGE_TOOL_CALLS
|
|
443
448
|
|
|
449
|
+
TOOL_CALL_ID = ToolCallAttributes.TOOL_CALL_ID
|
|
444
450
|
TOOL_CALL_FUNCTION_NAME = ToolCallAttributes.TOOL_CALL_FUNCTION_NAME
|
|
445
451
|
TOOL_CALL_FUNCTION_ARGUMENTS_JSON = ToolCallAttributes.TOOL_CALL_FUNCTION_ARGUMENTS_JSON
|
|
446
452
|
TOOL_CALL_ID = ToolCallAttributes.TOOL_CALL_ID
|
{arize_phoenix-5.10.0 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/chat_mutations.py
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from dataclasses import asdict, field
|
|
3
3
|
from datetime import datetime, timezone
|
|
4
|
-
from itertools import chain
|
|
4
|
+
from itertools import chain, islice
|
|
5
5
|
from traceback import format_exc
|
|
6
|
-
from typing import Any, Iterable, Iterator, List, Optional, Union
|
|
6
|
+
from typing import Any, Iterable, Iterator, List, Optional, TypeVar, Union
|
|
7
7
|
|
|
8
8
|
import strawberry
|
|
9
9
|
from openinference.instrumentation import safe_json_dumps
|
|
@@ -26,7 +26,7 @@ from phoenix.datetime_utils import local_now, normalize_datetime
|
|
|
26
26
|
from phoenix.db import models
|
|
27
27
|
from phoenix.db.helpers import get_dataset_example_revisions
|
|
28
28
|
from phoenix.server.api.context import Context
|
|
29
|
-
from phoenix.server.api.exceptions import BadRequest, NotFound
|
|
29
|
+
from phoenix.server.api.exceptions import BadRequest, CustomGraphQLError, NotFound
|
|
30
30
|
from phoenix.server.api.helpers.playground_clients import (
|
|
31
31
|
PlaygroundStreamingClient,
|
|
32
32
|
initialize_playground_clients,
|
|
@@ -127,11 +127,19 @@ class ChatCompletionMutationMixin:
|
|
|
127
127
|
provider_key = input.model.provider_key
|
|
128
128
|
llm_client_class = PLAYGROUND_CLIENT_REGISTRY.get_client(provider_key, input.model.name)
|
|
129
129
|
if llm_client_class is None:
|
|
130
|
-
raise BadRequest(f"
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
raise BadRequest(f"Unknown LLM provider: '{provider_key.value}'")
|
|
131
|
+
try:
|
|
132
|
+
llm_client = llm_client_class(
|
|
133
|
+
model=input.model,
|
|
134
|
+
api_key=input.api_key,
|
|
135
|
+
)
|
|
136
|
+
except CustomGraphQLError:
|
|
137
|
+
raise
|
|
138
|
+
except Exception as error:
|
|
139
|
+
raise BadRequest(
|
|
140
|
+
f"Failed to connect to LLM API for {provider_key.value} {input.model.name}: "
|
|
141
|
+
f"{str(error)}"
|
|
142
|
+
)
|
|
135
143
|
dataset_id = from_global_id_with_expected_type(input.dataset_id, Dataset.__name__)
|
|
136
144
|
dataset_version_id = (
|
|
137
145
|
from_global_id_with_expected_type(
|
|
@@ -158,7 +166,9 @@ class ChatCompletionMutationMixin:
|
|
|
158
166
|
revisions = [
|
|
159
167
|
revision
|
|
160
168
|
async for revision in await session.stream_scalars(
|
|
161
|
-
get_dataset_example_revisions(resolved_version_id)
|
|
169
|
+
get_dataset_example_revisions(resolved_version_id).order_by(
|
|
170
|
+
models.DatasetExampleRevision.id
|
|
171
|
+
)
|
|
162
172
|
)
|
|
163
173
|
]
|
|
164
174
|
if not revisions:
|
|
@@ -181,28 +191,32 @@ class ChatCompletionMutationMixin:
|
|
|
181
191
|
session.add(experiment)
|
|
182
192
|
await session.flush()
|
|
183
193
|
|
|
194
|
+
results = []
|
|
195
|
+
batch_size = 3
|
|
184
196
|
start_time = datetime.now(timezone.utc)
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
for batch in _get_batches(revisions, batch_size):
|
|
198
|
+
batch_results = await asyncio.gather(
|
|
199
|
+
*(
|
|
200
|
+
cls._chat_completion(
|
|
201
|
+
info,
|
|
202
|
+
llm_client,
|
|
203
|
+
ChatCompletionInput(
|
|
204
|
+
model=input.model,
|
|
205
|
+
api_key=input.api_key,
|
|
206
|
+
messages=input.messages,
|
|
207
|
+
tools=input.tools,
|
|
208
|
+
invocation_parameters=input.invocation_parameters,
|
|
209
|
+
template=TemplateOptions(
|
|
210
|
+
language=input.template_language,
|
|
211
|
+
variables=revision.input,
|
|
212
|
+
),
|
|
199
213
|
),
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
214
|
+
)
|
|
215
|
+
for revision in batch
|
|
216
|
+
),
|
|
217
|
+
return_exceptions=True,
|
|
218
|
+
)
|
|
219
|
+
results.extend(batch_results)
|
|
206
220
|
|
|
207
221
|
payload = ChatCompletionOverDatasetMutationPayload(
|
|
208
222
|
dataset_id=GlobalID(models.Dataset.__name__, str(dataset.id)),
|
|
@@ -266,11 +280,19 @@ class ChatCompletionMutationMixin:
|
|
|
266
280
|
provider_key = input.model.provider_key
|
|
267
281
|
llm_client_class = PLAYGROUND_CLIENT_REGISTRY.get_client(provider_key, input.model.name)
|
|
268
282
|
if llm_client_class is None:
|
|
269
|
-
raise BadRequest(f"
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
283
|
+
raise BadRequest(f"Unknown LLM provider: '{provider_key.value}'")
|
|
284
|
+
try:
|
|
285
|
+
llm_client = llm_client_class(
|
|
286
|
+
model=input.model,
|
|
287
|
+
api_key=input.api_key,
|
|
288
|
+
)
|
|
289
|
+
except CustomGraphQLError:
|
|
290
|
+
raise
|
|
291
|
+
except Exception as error:
|
|
292
|
+
raise BadRequest(
|
|
293
|
+
f"Failed to connect to LLM API for {provider_key.value} {input.model.name}: "
|
|
294
|
+
f"{str(error)}"
|
|
295
|
+
)
|
|
274
296
|
return await cls._chat_completion(info, llm_client, input)
|
|
275
297
|
|
|
276
298
|
@classmethod
|
|
@@ -486,6 +508,11 @@ def _llm_output_messages(
|
|
|
486
508
|
if text_content:
|
|
487
509
|
yield f"{LLM_OUTPUT_MESSAGES}.0.{MESSAGE_CONTENT}", text_content
|
|
488
510
|
for tool_call_index, tool_call in enumerate(tool_calls.values()):
|
|
511
|
+
if tool_call_id := tool_call.id:
|
|
512
|
+
yield (
|
|
513
|
+
f"{LLM_OUTPUT_MESSAGES}.0.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_ID}",
|
|
514
|
+
tool_call_id,
|
|
515
|
+
)
|
|
489
516
|
yield (
|
|
490
517
|
f"{LLM_OUTPUT_MESSAGES}.0.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_FUNCTION_NAME}",
|
|
491
518
|
tool_call.function.name,
|
|
@@ -513,6 +540,19 @@ def _serialize_event(event: SpanException) -> dict[str, Any]:
|
|
|
513
540
|
return {k: (v.isoformat() if isinstance(v, datetime) else v) for k, v in asdict(event).items()}
|
|
514
541
|
|
|
515
542
|
|
|
543
|
+
_AnyT = TypeVar("_AnyT")
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
def _get_batches(
|
|
547
|
+
iterable: Iterable[_AnyT],
|
|
548
|
+
batch_size: int,
|
|
549
|
+
) -> Iterator[list[_AnyT]]:
|
|
550
|
+
"""Splits an iterable into batches not exceeding a specified size."""
|
|
551
|
+
iterator = iter(iterable)
|
|
552
|
+
while batch := list(islice(iterator, batch_size)):
|
|
553
|
+
yield batch
|
|
554
|
+
|
|
555
|
+
|
|
516
556
|
JSON = OpenInferenceMimeTypeValues.JSON.value
|
|
517
557
|
TEXT = OpenInferenceMimeTypeValues.TEXT.value
|
|
518
558
|
LLM = OpenInferenceSpanKindValues.LLM.value
|
|
@@ -534,6 +574,7 @@ MESSAGE_CONTENT = MessageAttributes.MESSAGE_CONTENT
|
|
|
534
574
|
MESSAGE_ROLE = MessageAttributes.MESSAGE_ROLE
|
|
535
575
|
MESSAGE_TOOL_CALLS = MessageAttributes.MESSAGE_TOOL_CALLS
|
|
536
576
|
|
|
577
|
+
TOOL_CALL_ID = ToolCallAttributes.TOOL_CALL_ID
|
|
537
578
|
TOOL_CALL_FUNCTION_NAME = ToolCallAttributes.TOOL_CALL_FUNCTION_NAME
|
|
538
579
|
TOOL_CALL_FUNCTION_ARGUMENTS_JSON = ToolCallAttributes.TOOL_CALL_FUNCTION_ARGUMENTS_JSON
|
|
539
580
|
|
|
@@ -2,9 +2,10 @@ import asyncio
|
|
|
2
2
|
import logging
|
|
3
3
|
from asyncio import FIRST_COMPLETED, Queue, QueueEmpty, Task, create_task, wait, wait_for
|
|
4
4
|
from collections.abc import AsyncIterator, Iterator
|
|
5
|
-
from datetime import datetime, timezone
|
|
5
|
+
from datetime import datetime, timedelta, timezone
|
|
6
6
|
from typing import (
|
|
7
7
|
Any,
|
|
8
|
+
AsyncGenerator,
|
|
8
9
|
Iterable,
|
|
9
10
|
Mapping,
|
|
10
11
|
Optional,
|
|
@@ -24,7 +25,7 @@ from typing_extensions import TypeAlias, assert_never
|
|
|
24
25
|
from phoenix.datetime_utils import local_now, normalize_datetime
|
|
25
26
|
from phoenix.db import models
|
|
26
27
|
from phoenix.server.api.context import Context
|
|
27
|
-
from phoenix.server.api.exceptions import BadRequest, NotFound
|
|
28
|
+
from phoenix.server.api.exceptions import BadRequest, CustomGraphQLError, NotFound
|
|
28
29
|
from phoenix.server.api.helpers.playground_clients import (
|
|
29
30
|
PlaygroundStreamingClient,
|
|
30
31
|
initialize_playground_clients,
|
|
@@ -79,6 +80,7 @@ DatasetExampleID: TypeAlias = GlobalID
|
|
|
79
80
|
ChatCompletionResult: TypeAlias = tuple[
|
|
80
81
|
DatasetExampleID, Optional[models.Span], models.ExperimentRun
|
|
81
82
|
]
|
|
83
|
+
ChatStream: TypeAlias = AsyncGenerator[ChatCompletionSubscriptionPayload, None]
|
|
82
84
|
PLAYGROUND_PROJECT_NAME = "playground"
|
|
83
85
|
|
|
84
86
|
|
|
@@ -91,11 +93,19 @@ class Subscription:
|
|
|
91
93
|
provider_key = input.model.provider_key
|
|
92
94
|
llm_client_class = PLAYGROUND_CLIENT_REGISTRY.get_client(provider_key, input.model.name)
|
|
93
95
|
if llm_client_class is None:
|
|
94
|
-
raise BadRequest(f"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
raise BadRequest(f"Unknown LLM provider: '{provider_key.value}'")
|
|
97
|
+
try:
|
|
98
|
+
llm_client = llm_client_class(
|
|
99
|
+
model=input.model,
|
|
100
|
+
api_key=input.api_key,
|
|
101
|
+
)
|
|
102
|
+
except CustomGraphQLError:
|
|
103
|
+
raise
|
|
104
|
+
except Exception as error:
|
|
105
|
+
raise BadRequest(
|
|
106
|
+
f"Failed to connect to LLM API for {provider_key.value} {input.model.name}: "
|
|
107
|
+
f"{str(error)}"
|
|
108
|
+
)
|
|
99
109
|
|
|
100
110
|
messages = [
|
|
101
111
|
(
|
|
@@ -158,7 +168,19 @@ class Subscription:
|
|
|
158
168
|
provider_key = input.model.provider_key
|
|
159
169
|
llm_client_class = PLAYGROUND_CLIENT_REGISTRY.get_client(provider_key, input.model.name)
|
|
160
170
|
if llm_client_class is None:
|
|
161
|
-
raise BadRequest(f"
|
|
171
|
+
raise BadRequest(f"Unknown LLM provider: '{provider_key.value}'")
|
|
172
|
+
try:
|
|
173
|
+
llm_client = llm_client_class(
|
|
174
|
+
model=input.model,
|
|
175
|
+
api_key=input.api_key,
|
|
176
|
+
)
|
|
177
|
+
except CustomGraphQLError:
|
|
178
|
+
raise
|
|
179
|
+
except Exception as error:
|
|
180
|
+
raise BadRequest(
|
|
181
|
+
f"Failed to connect to LLM API for {provider_key.value} {input.model.name}: "
|
|
182
|
+
f"{str(error)}"
|
|
183
|
+
)
|
|
162
184
|
|
|
163
185
|
dataset_id = from_global_id_with_expected_type(input.dataset_id, Dataset.__name__)
|
|
164
186
|
version_id = (
|
|
@@ -264,45 +286,76 @@ class Subscription:
|
|
|
264
286
|
experiment=to_gql_experiment(experiment)
|
|
265
287
|
) # eagerly yields experiment so it can be linked by consumers of the subscription
|
|
266
288
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
289
|
+
results: Queue[ChatCompletionResult] = Queue()
|
|
290
|
+
not_started: list[tuple[DatasetExampleID, ChatStream]] = [
|
|
291
|
+
(
|
|
292
|
+
GlobalID(DatasetExample.__name__, str(revision.dataset_example_id)),
|
|
293
|
+
_stream_chat_completion_over_dataset_example(
|
|
294
|
+
input=input,
|
|
295
|
+
llm_client=llm_client,
|
|
296
|
+
revision=revision,
|
|
297
|
+
results=results,
|
|
298
|
+
experiment_id=experiment.id,
|
|
299
|
+
project_id=playground_project_id,
|
|
300
|
+
),
|
|
276
301
|
)
|
|
277
302
|
for revision in revisions
|
|
278
303
|
]
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
304
|
+
in_progress: list[
|
|
305
|
+
tuple[Optional[DatasetExampleID], ChatStream, Task[ChatCompletionSubscriptionPayload]]
|
|
306
|
+
] = []
|
|
307
|
+
max_in_progress = 3
|
|
308
|
+
write_batch_size = 10
|
|
309
|
+
write_interval = timedelta(seconds=10)
|
|
310
|
+
last_write_time = datetime.now()
|
|
311
|
+
while not_started or in_progress:
|
|
312
|
+
while not_started and len(in_progress) < max_in_progress:
|
|
313
|
+
ex_id, stream = not_started.pop()
|
|
314
|
+
task = _create_task_with_timeout(stream)
|
|
315
|
+
in_progress.append((ex_id, stream, task))
|
|
316
|
+
async_tasks_to_run = [task for _, _, task in in_progress]
|
|
286
317
|
completed_tasks, _ = await wait(async_tasks_to_run, return_when=FIRST_COMPLETED)
|
|
287
|
-
for
|
|
288
|
-
|
|
318
|
+
for completed_task in completed_tasks:
|
|
319
|
+
idx = [task for _, _, task in in_progress].index(completed_task)
|
|
320
|
+
example_id, stream, _ = in_progress[idx]
|
|
289
321
|
try:
|
|
290
|
-
yield
|
|
291
|
-
except
|
|
292
|
-
del
|
|
322
|
+
yield completed_task.result()
|
|
323
|
+
except StopAsyncIteration:
|
|
324
|
+
del in_progress[idx] # removes exhausted stream
|
|
325
|
+
except asyncio.TimeoutError:
|
|
326
|
+
del in_progress[idx] # removes timed-out stream
|
|
327
|
+
if example_id is not None:
|
|
328
|
+
yield ChatCompletionSubscriptionError(
|
|
329
|
+
message="Timed out", dataset_example_id=example_id
|
|
330
|
+
)
|
|
293
331
|
except Exception as error:
|
|
294
|
-
del
|
|
332
|
+
del in_progress[idx] # removes failed stream
|
|
333
|
+
if example_id is not None:
|
|
334
|
+
yield ChatCompletionSubscriptionError(
|
|
335
|
+
message="An unexpected error occurred", dataset_example_id=example_id
|
|
336
|
+
)
|
|
295
337
|
logger.exception(error)
|
|
296
338
|
else:
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
339
|
+
task = _create_task_with_timeout(stream)
|
|
340
|
+
in_progress[idx] = (example_id, stream, task)
|
|
341
|
+
|
|
342
|
+
exceeded_write_batch_size = results.qsize() >= write_batch_size
|
|
343
|
+
exceeded_write_interval = datetime.now() - last_write_time > write_interval
|
|
344
|
+
write_already_in_progress = any(
|
|
345
|
+
_is_result_payloads_stream(stream) for _, stream, _ in in_progress
|
|
346
|
+
)
|
|
347
|
+
if (
|
|
348
|
+
not results.empty()
|
|
349
|
+
and (exceeded_write_batch_size or exceeded_write_interval)
|
|
350
|
+
and not write_already_in_progress
|
|
351
|
+
):
|
|
352
|
+
result_payloads_stream = _chat_completion_result_payloads(
|
|
353
|
+
db=info.context.db, results=_drain_no_wait(results)
|
|
304
354
|
)
|
|
305
|
-
|
|
355
|
+
task = _create_task_with_timeout(result_payloads_stream)
|
|
356
|
+
in_progress.append((None, result_payloads_stream, task))
|
|
357
|
+
last_write_time = datetime.now()
|
|
358
|
+
if remaining_results := await _drain(results):
|
|
306
359
|
async for result_payload in _chat_completion_result_payloads(
|
|
307
360
|
db=info.context.db, results=remaining_results
|
|
308
361
|
):
|
|
@@ -312,17 +365,13 @@ class Subscription:
|
|
|
312
365
|
async def _stream_chat_completion_over_dataset_example(
|
|
313
366
|
*,
|
|
314
367
|
input: ChatCompletionOverDatasetInput,
|
|
315
|
-
|
|
368
|
+
llm_client: PlaygroundStreamingClient,
|
|
316
369
|
revision: models.DatasetExampleRevision,
|
|
317
|
-
|
|
370
|
+
results: Queue[ChatCompletionResult],
|
|
318
371
|
experiment_id: int,
|
|
319
372
|
project_id: int,
|
|
320
|
-
) ->
|
|
373
|
+
) -> ChatStream:
|
|
321
374
|
example_id = GlobalID(DatasetExample.__name__, str(revision.dataset_example_id))
|
|
322
|
-
llm_client = llm_client_class(
|
|
323
|
-
model=input.model,
|
|
324
|
-
api_key=input.api_key,
|
|
325
|
-
)
|
|
326
375
|
invocation_parameters = llm_client.construct_invocation_parameters(input.invocation_parameters)
|
|
327
376
|
messages = [
|
|
328
377
|
(
|
|
@@ -345,7 +394,7 @@ async def _stream_chat_completion_over_dataset_example(
|
|
|
345
394
|
except TemplateFormatterError as error:
|
|
346
395
|
format_end_time = cast(datetime, normalize_datetime(dt=local_now(), tz=timezone.utc))
|
|
347
396
|
yield ChatCompletionSubscriptionError(message=str(error), dataset_example_id=example_id)
|
|
348
|
-
await
|
|
397
|
+
await results.put(
|
|
349
398
|
(
|
|
350
399
|
example_id,
|
|
351
400
|
None,
|
|
@@ -380,7 +429,7 @@ async def _stream_chat_completion_over_dataset_example(
|
|
|
380
429
|
db_run = get_db_experiment_run(
|
|
381
430
|
db_span, db_trace, experiment_id=experiment_id, example_id=revision.dataset_example_id
|
|
382
431
|
)
|
|
383
|
-
await
|
|
432
|
+
await results.put((example_id, db_span, db_run))
|
|
384
433
|
if span.status_message is not None:
|
|
385
434
|
yield ChatCompletionSubscriptionError(
|
|
386
435
|
message=span.status_message, dataset_example_id=example_id
|
|
@@ -391,7 +440,7 @@ async def _chat_completion_result_payloads(
|
|
|
391
440
|
*,
|
|
392
441
|
db: DbSessionFactory,
|
|
393
442
|
results: Sequence[ChatCompletionResult],
|
|
394
|
-
) ->
|
|
443
|
+
) -> ChatStream:
|
|
395
444
|
if not results:
|
|
396
445
|
return
|
|
397
446
|
async with db() as session:
|
|
@@ -408,8 +457,18 @@ async def _chat_completion_result_payloads(
|
|
|
408
457
|
)
|
|
409
458
|
|
|
410
459
|
|
|
460
|
+
def _is_result_payloads_stream(
|
|
461
|
+
stream: ChatStream,
|
|
462
|
+
) -> bool:
|
|
463
|
+
"""
|
|
464
|
+
Checks if the given generator was instantiated from
|
|
465
|
+
`_chat_completion_result_payloads`
|
|
466
|
+
"""
|
|
467
|
+
return stream.ag_code == _chat_completion_result_payloads.__code__
|
|
468
|
+
|
|
469
|
+
|
|
411
470
|
def _create_task_with_timeout(
|
|
412
|
-
iterable: AsyncIterator[GenericType], timeout_in_seconds: int =
|
|
471
|
+
iterable: AsyncIterator[GenericType], timeout_in_seconds: int = 90
|
|
413
472
|
) -> Task[GenericType]:
|
|
414
473
|
return create_task(wait_for(_as_coroutine(iterable), timeout=timeout_in_seconds))
|
|
415
474
|
|