arize-phoenix 5.9.1__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.

Files changed (333) hide show
  1. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/PKG-INFO +2 -1
  2. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/pyproject.toml +1 -0
  3. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/config.py +16 -1
  4. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/facilitator.py +3 -2
  5. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/playground_clients.py +73 -19
  6. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/playground_spans.py +40 -8
  7. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/chat_mutations.py +75 -34
  8. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/subscriptions.py +109 -50
  9. arize_phoenix-5.11.0/src/phoenix/server/api/types/GenerativeProvider.py +85 -0
  10. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Span.py +4 -5
  11. arize_phoenix-5.11.0/src/phoenix/server/static/.vite/manifest.json +78 -0
  12. arize_phoenix-5.9.1/src/phoenix/server/static/assets/components-BcvRmBnN.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/components-C_HASv83.js +131 -131
  13. arize_phoenix-5.9.1/src/phoenix/server/static/assets/index-BF4RUiOz.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/index-D7UiCRtr.js +2 -2
  14. arize_phoenix-5.9.1/src/phoenix/server/static/assets/pages-CM_Zho_x.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/pages-DYHcAdjT.js +315 -266
  15. arize_phoenix-5.9.1/src/phoenix/server/static/assets/vendor-Bjm5T3cE.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/vendor-BCxsh5i3.js +153 -153
  16. arize_phoenix-5.9.1/src/phoenix/server/static/assets/vendor-arizeai-CQhWGEdL.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/vendor-arizeai-C2CDZgMz.js +28 -28
  17. arize_phoenix-5.9.1/src/phoenix/server/static/assets/vendor-codemirror-CdtiO80y.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/vendor-codemirror-DYbtnCTn.js +2 -2
  18. arize_phoenix-5.9.1/src/phoenix/server/static/assets/vendor-recharts-BqWon6Py.js → arize_phoenix-5.11.0/src/phoenix/server/static/assets/vendor-recharts-P6W8G0Mb.js +1 -1
  19. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/span_evaluations.py +4 -3
  20. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/utilities/json.py +7 -1
  21. arize_phoenix-5.11.0/src/phoenix/version.py +1 -0
  22. arize_phoenix-5.9.1/src/phoenix/server/api/types/GenerativeProvider.py +0 -41
  23. arize_phoenix-5.9.1/src/phoenix/server/static/.vite/manifest.json +0 -78
  24. arize_phoenix-5.9.1/src/phoenix/version.py +0 -1
  25. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/.gitignore +0 -0
  26. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/IP_NOTICE +0 -0
  27. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/LICENSE +0 -0
  28. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/README.md +0 -0
  29. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/__init__.py +0 -0
  30. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/auth.py +0 -0
  31. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/core/__init__.py +0 -0
  32. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/core/embedding_dimension.py +0 -0
  33. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/core/model.py +0 -0
  34. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/core/model_schema.py +0 -0
  35. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/core/model_schema_adapter.py +0 -0
  36. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/datetime_utils.py +0 -0
  37. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/README.md +0 -0
  38. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/__init__.py +0 -0
  39. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/alembic.ini +0 -0
  40. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/bulk_inserter.py +0 -0
  41. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/engines.py +0 -0
  42. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/enums.py +0 -0
  43. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/helpers.py +0 -0
  44. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/__init__.py +0 -0
  45. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/constants.py +0 -0
  46. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/dataset.py +0 -0
  47. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/document_annotation.py +0 -0
  48. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/evaluation.py +0 -0
  49. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/helpers.py +0 -0
  50. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/span.py +0 -0
  51. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/span_annotation.py +0 -0
  52. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/trace_annotation.py +0 -0
  53. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/insertion/types.py +0 -0
  54. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/migrate.py +0 -0
  55. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/__init__.py +0 -0
  56. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/env.py +0 -0
  57. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/script.py.mako +0 -0
  58. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -0
  59. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/versions/3be8647b87d8_add_token_columns_to_spans_table.py +0 -0
  60. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/versions/cd164e83824f_users_and_tokens.py +0 -0
  61. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/migrations/versions/cf03bd6bae1d_init.py +0 -0
  62. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/db/models.py +0 -0
  63. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/exceptions.py +0 -0
  64. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/experiments/__init__.py +0 -0
  65. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/experiments/evaluators/__init__.py +0 -0
  66. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/experiments/evaluators/base.py +0 -0
  67. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/experiments/evaluators/code_evaluators.py +0 -0
  68. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/experiments/evaluators/llm_evaluators.py +0 -0
  69. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/experiments/evaluators/utils.py +0 -0
  70. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/experiments/functions.py +0 -0
  71. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/experiments/tracing.py +0 -0
  72. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/experiments/types.py +0 -0
  73. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/experiments/utils.py +0 -0
  74. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/inferences/__init__.py +0 -0
  75. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/inferences/errors.py +0 -0
  76. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/inferences/fixtures.py +0 -0
  77. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/inferences/inferences.py +0 -0
  78. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/inferences/schema.py +0 -0
  79. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/inferences/validation.py +0 -0
  80. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/logging/__init__.py +0 -0
  81. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/logging/_config.py +0 -0
  82. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/logging/_filter.py +0 -0
  83. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/logging/_formatter.py +0 -0
  84. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/metrics/README.md +0 -0
  85. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/metrics/__init__.py +0 -0
  86. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/metrics/binning.py +0 -0
  87. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/metrics/metrics.py +0 -0
  88. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/metrics/mixins.py +0 -0
  89. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/metrics/retrieval_metrics.py +0 -0
  90. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/metrics/timeseries.py +0 -0
  91. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/metrics/wrappers.py +0 -0
  92. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/pointcloud/__init__.py +0 -0
  93. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/pointcloud/clustering.py +0 -0
  94. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/pointcloud/pointcloud.py +0 -0
  95. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/pointcloud/projectors.py +0 -0
  96. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/pointcloud/umap_parameters.py +0 -0
  97. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/py.typed +0 -0
  98. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/__init__.py +0 -0
  99. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/README.md +0 -0
  100. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/__init__.py +0 -0
  101. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/auth.py +0 -0
  102. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/context.py +0 -0
  103. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/__init__.py +0 -0
  104. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/annotation_summaries.py +0 -0
  105. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/average_experiment_run_latency.py +0 -0
  106. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/cache/__init__.py +0 -0
  107. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/cache/two_tier_cache.py +0 -0
  108. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -0
  109. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/dataset_example_spans.py +0 -0
  110. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/document_evaluation_summaries.py +0 -0
  111. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/document_evaluations.py +0 -0
  112. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/document_retrieval_metrics.py +0 -0
  113. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/experiment_annotation_summaries.py +0 -0
  114. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/experiment_error_rates.py +0 -0
  115. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/experiment_run_annotations.py +0 -0
  116. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/experiment_run_counts.py +0 -0
  117. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/experiment_sequence_number.py +0 -0
  118. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/latency_ms_quantile.py +0 -0
  119. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/min_start_or_max_end_times.py +0 -0
  120. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/project_by_name.py +0 -0
  121. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/record_counts.py +0 -0
  122. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/span_annotations.py +0 -0
  123. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/span_dataset_examples.py +0 -0
  124. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/span_descendants.py +0 -0
  125. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/span_projects.py +0 -0
  126. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/token_counts.py +0 -0
  127. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/trace_row_ids.py +0 -0
  128. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/user_roles.py +0 -0
  129. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/dataloaders/users.py +0 -0
  130. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/exceptions.py +0 -0
  131. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/__init__.py +0 -0
  132. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/dataset_helpers.py +0 -0
  133. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/helpers/playground_registry.py +0 -0
  134. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -0
  135. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -0
  136. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/ChatCompletionInput.py +0 -0
  137. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/ChatCompletionMessageInput.py +0 -0
  138. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/ClearProjectInput.py +0 -0
  139. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/ClusterInput.py +0 -0
  140. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/Coordinates.py +0 -0
  141. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/CreateDatasetInput.py +0 -0
  142. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/CreateSpanAnnotationInput.py +0 -0
  143. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/CreateTraceAnnotationInput.py +0 -0
  144. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DataQualityMetricInput.py +0 -0
  145. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DatasetExampleInput.py +0 -0
  146. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DatasetSort.py +0 -0
  147. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DatasetVersionSort.py +0 -0
  148. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DeleteAnnotationsInput.py +0 -0
  149. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -0
  150. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DeleteDatasetInput.py +0 -0
  151. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -0
  152. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DimensionFilter.py +0 -0
  153. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/DimensionInput.py +0 -0
  154. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/GenerativeModelInput.py +0 -0
  155. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/Granularity.py +0 -0
  156. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/InvocationParameters.py +0 -0
  157. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/PatchAnnotationInput.py +0 -0
  158. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -0
  159. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/PatchDatasetInput.py +0 -0
  160. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/PerformanceMetricInput.py +0 -0
  161. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/SpanAnnotationSort.py +0 -0
  162. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/SpanSort.py +0 -0
  163. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/TemplateOptions.py +0 -0
  164. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/TimeRange.py +0 -0
  165. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/TraceAnnotationSort.py +0 -0
  166. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/UserRoleInput.py +0 -0
  167. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/input_types/__init__.py +0 -0
  168. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/interceptor.py +0 -0
  169. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/__init__.py +0 -0
  170. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/api_key_mutations.py +0 -0
  171. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/dataset_mutations.py +0 -0
  172. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/experiment_mutations.py +0 -0
  173. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/export_events_mutations.py +0 -0
  174. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/project_mutations.py +0 -0
  175. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/span_annotations_mutations.py +0 -0
  176. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/trace_annotations_mutations.py +0 -0
  177. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/mutations/user_mutations.py +0 -0
  178. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/openapi/__init__.py +0 -0
  179. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/openapi/main.py +0 -0
  180. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/openapi/schema.py +0 -0
  181. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/queries.py +0 -0
  182. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/__init__.py +0 -0
  183. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/auth.py +0 -0
  184. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/embeddings.py +0 -0
  185. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/oauth2.py +0 -0
  186. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/utils.py +0 -0
  187. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/__init__.py +0 -0
  188. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/datasets.py +0 -0
  189. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/evaluations.py +0 -0
  190. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/experiment_evaluations.py +0 -0
  191. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/experiment_runs.py +0 -0
  192. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/experiments.py +0 -0
  193. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/pydantic_compat.py +0 -0
  194. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/spans.py +0 -0
  195. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/traces.py +0 -0
  196. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/routers/v1/utils.py +0 -0
  197. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/schema.py +0 -0
  198. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Annotation.py +0 -0
  199. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/AnnotationSummary.py +0 -0
  200. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/AnnotatorKind.py +0 -0
  201. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ApiKey.py +0 -0
  202. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/AuthMethod.py +0 -0
  203. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ChatCompletionMessageRole.py +0 -0
  204. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ChatCompletionSubscriptionPayload.py +0 -0
  205. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Cluster.py +0 -0
  206. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/CreateDatasetPayload.py +0 -0
  207. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DataQualityMetric.py +0 -0
  208. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Dataset.py +0 -0
  209. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DatasetExample.py +0 -0
  210. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DatasetExampleRevision.py +0 -0
  211. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DatasetValues.py +0 -0
  212. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DatasetVersion.py +0 -0
  213. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Dimension.py +0 -0
  214. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DimensionDataType.py +0 -0
  215. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DimensionShape.py +0 -0
  216. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DimensionType.py +0 -0
  217. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DimensionWithValue.py +0 -0
  218. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DocumentEvaluationSummary.py +0 -0
  219. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/DocumentRetrievalMetrics.py +0 -0
  220. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/EmbeddingDimension.py +0 -0
  221. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/EmbeddingMetadata.py +0 -0
  222. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Evaluation.py +0 -0
  223. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/EvaluationSummary.py +0 -0
  224. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Event.py +0 -0
  225. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/EventMetadata.py +0 -0
  226. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExampleRevisionInterface.py +0 -0
  227. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Experiment.py +0 -0
  228. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -0
  229. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExperimentComparison.py +0 -0
  230. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExperimentRun.py +0 -0
  231. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExperimentRunAnnotation.py +0 -0
  232. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ExportedFile.py +0 -0
  233. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Functionality.py +0 -0
  234. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/GenerativeModel.py +0 -0
  235. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Inferences.py +0 -0
  236. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/InferencesRole.py +0 -0
  237. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/LabelFraction.py +0 -0
  238. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/MimeType.py +0 -0
  239. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Model.py +0 -0
  240. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/NumericRange.py +0 -0
  241. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/PerformanceMetric.py +0 -0
  242. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Project.py +0 -0
  243. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/PromptResponse.py +0 -0
  244. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Retrieval.py +0 -0
  245. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ScalarDriftMetricEnum.py +0 -0
  246. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Segments.py +0 -0
  247. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/SortDir.py +0 -0
  248. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/SpanAnnotation.py +0 -0
  249. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/SystemApiKey.py +0 -0
  250. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/TemplateLanguage.py +0 -0
  251. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/TimeSeries.py +0 -0
  252. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/Trace.py +0 -0
  253. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/TraceAnnotation.py +0 -0
  254. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/UMAPPoints.py +0 -0
  255. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/User.py +0 -0
  256. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/UserApiKey.py +0 -0
  257. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/UserRole.py +0 -0
  258. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/ValidationResult.py +0 -0
  259. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/VectorDriftMetricEnum.py +0 -0
  260. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/__init__.py +0 -0
  261. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/node.py +0 -0
  262. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/types/pagination.py +0 -0
  263. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/api/utils.py +0 -0
  264. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/app.py +0 -0
  265. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/bearer_auth.py +0 -0
  266. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/dml_event.py +0 -0
  267. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/dml_event_handler.py +0 -0
  268. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/email/__init__.py +0 -0
  269. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/email/sender.py +0 -0
  270. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/email/templates/__init__.py +0 -0
  271. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/email/templates/password_reset.html +0 -0
  272. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/email/types.py +0 -0
  273. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/grpc_server.py +0 -0
  274. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/jwt_store.py +0 -0
  275. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/main.py +0 -0
  276. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/oauth2.py +0 -0
  277. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/openapi/__init__.py +0 -0
  278. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/prometheus.py +0 -0
  279. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/rate_limiters.py +0 -0
  280. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-114x114.png +0 -0
  281. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-120x120.png +0 -0
  282. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-144x144.png +0 -0
  283. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-152x152.png +0 -0
  284. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-180x180.png +0 -0
  285. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-72x72.png +0 -0
  286. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon-76x76.png +0 -0
  287. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/apple-touch-icon.png +0 -0
  288. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/assets/vendor-DxkFTwjz.css +0 -0
  289. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/assets/vendor-three-DwGkEfCM.js +0 -0
  290. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/favicon.ico +0 -0
  291. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/static/modernizr.js +0 -0
  292. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/telemetry.py +0 -0
  293. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/templates/__init__.py +0 -0
  294. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/templates/index.html +0 -0
  295. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/thread_server.py +0 -0
  296. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/server/types.py +0 -0
  297. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/services.py +0 -0
  298. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/session/__init__.py +0 -0
  299. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/session/client.py +0 -0
  300. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/session/data_extractor.py +0 -0
  301. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/session/evaluation.py +0 -0
  302. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/session/session.py +0 -0
  303. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/settings.py +0 -0
  304. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/__init__.py +0 -0
  305. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/attributes.py +0 -0
  306. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/dsl/README.md +0 -0
  307. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/dsl/__init__.py +0 -0
  308. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/dsl/filter.py +0 -0
  309. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/dsl/helpers.py +0 -0
  310. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/dsl/query.py +0 -0
  311. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/errors.py +0 -0
  312. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/evaluation_conventions.py +0 -0
  313. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/exporter.py +0 -0
  314. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/fixtures.py +0 -0
  315. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/otel.py +0 -0
  316. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/projects.py +0 -0
  317. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/schemas.py +0 -0
  318. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/span_json_decoder.py +0 -0
  319. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/span_json_encoder.py +0 -0
  320. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/trace_dataset.py +0 -0
  321. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/utils.py +0 -0
  322. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/v1/__init__.py +0 -0
  323. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/v1/evaluation_pb2.py +0 -0
  324. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/trace/v1/evaluation_pb2.pyi +0 -0
  325. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/utilities/__init__.py +0 -0
  326. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/utilities/client.py +0 -0
  327. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/utilities/deprecation.py +0 -0
  328. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/utilities/error_handling.py +0 -0
  329. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/utilities/logging.py +0 -0
  330. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/utilities/project.py +0 -0
  331. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/utilities/re.py +0 -0
  332. {arize_phoenix-5.9.1 → arize_phoenix-5.11.0}/src/phoenix/utilities/span_store.py +0 -0
  333. {arize_phoenix-5.9.1 → 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.9.1
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'
@@ -121,6 +121,7 @@ pg = [
121
121
  ]
122
122
  container = [
123
123
  "anthropic",
124
+ "google-generativeai",
124
125
  "prometheus-client",
125
126
  "openai>=1.0.0",
126
127
  "opentelemetry-sdk",
@@ -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
 
@@ -424,7 +437,9 @@ class OAuth2ClientConfig:
424
437
  f"An OpenID Connect configuration URL must be set for the {idp_name} OAuth2 IDP "
425
438
  f"via the {oidc_config_url_env_var} environment variable"
426
439
  )
427
- if urlparse(oidc_config_url).scheme != "https":
440
+ parsed_oidc_config_url = urlparse(oidc_config_url)
441
+ is_local_oidc_config_url = parsed_oidc_config_url.hostname in ("localhost", "127.0.0.1")
442
+ if parsed_oidc_config_url.scheme != "https" and not is_local_oidc_config_url:
428
443
  raise ValueError(
429
444
  f"Server metadata URL for {idp_name} OAuth2 IDP "
430
445
  "must be a valid URL using the https protocol"
@@ -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
- compute = partial(compute_password_hash, password=DEFAULT_ADMIN_PASSWORD, salt=salt)
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(
@@ -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
@@ -9,7 +10,11 @@ from functools import wraps
9
10
  from typing import TYPE_CHECKING, Any, Hashable, Mapping, Optional, Union
10
11
 
11
12
  from openinference.instrumentation import safe_json_dumps
12
- from openinference.semconv.trace import SpanAttributes
13
+ from openinference.semconv.trace import (
14
+ OpenInferenceLLMProviderValues,
15
+ OpenInferenceLLMSystemValues,
16
+ SpanAttributes,
17
+ )
13
18
  from strawberry import UNSET
14
19
  from strawberry.scalars import JSON as JSONScalarType
15
20
  from typing_extensions import TypeAlias, assert_never
@@ -21,6 +26,7 @@ from phoenix.evals.models.rate_limiters import (
21
26
  RateLimiter,
22
27
  RateLimitError,
23
28
  )
29
+ from phoenix.server.api.exceptions import BadRequest
24
30
  from phoenix.server.api.helpers.playground_registry import PROVIDER_DEFAULT, register_llm_client
25
31
  from phoenix.server.api.input_types.GenerativeModelInput import GenerativeModelInput
26
32
  from phoenix.server.api.input_types.InvocationParameters import (
@@ -44,7 +50,7 @@ from phoenix.server.api.types.ChatCompletionSubscriptionPayload import (
44
50
  from phoenix.server.api.types.GenerativeProvider import GenerativeProviderKey
45
51
 
46
52
  if TYPE_CHECKING:
47
- from anthropic.types import MessageParam
53
+ from anthropic.types import MessageParam, TextBlockParam, ToolResultBlockParam
48
54
  from google.generativeai.types import ContentType
49
55
  from openai.types import CompletionUsage
50
56
  from openai.types.chat import ChatCompletionMessageParam, ChatCompletionMessageToolCallParam
@@ -95,9 +101,9 @@ class PlaygroundRateLimiter(RateLimiter, KeyedSingleton):
95
101
  super().__init__(
96
102
  rate_limit_error=rate_limit_error,
97
103
  max_rate_limit_retries=3,
98
- initial_per_second_request_rate=2.0,
99
- maximum_per_second_request_rate=10.0,
100
- enforcement_window_minutes=1,
104
+ initial_per_second_request_rate=1.0,
105
+ maximum_per_second_request_rate=3.0,
106
+ enforcement_window_minutes=0.05,
101
107
  rate_reduction_factor=0.5,
102
108
  rate_increase_factor=0.01,
103
109
  cooldown_seconds=5,
@@ -124,10 +130,11 @@ class PlaygroundRateLimiter(RateLimiter, KeyedSingleton):
124
130
  self._rate_limit_handling.set() # Set the event as a failsafe
125
131
  await self._throttler.async_wait_until_ready()
126
132
  request_start_time = time.time()
127
- if inspect.iscoroutinefunction(fn):
128
- return await fn(*args, **kwargs) # type: ignore
133
+ maybe_coroutine = fn(*args, **kwargs)
134
+ if inspect.iscoroutine(maybe_coroutine):
135
+ return await maybe_coroutine # type: ignore
129
136
  else:
130
- return fn(*args, **kwargs)
137
+ return maybe_coroutine
131
138
  except self._rate_limit_error:
132
139
  async with self._rate_limit_handling_lock:
133
140
  self._rate_limit_handling.clear() # prevent new requests from starting
@@ -254,7 +261,13 @@ class OpenAIStreamingClient(PlaygroundStreamingClient):
254
261
  from openai import AsyncOpenAI
255
262
  from openai import RateLimitError as OpenAIRateLimitError
256
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")
257
268
  super().__init__(model=model, api_key=api_key)
269
+ self._attributes[LLM_PROVIDER] = OpenInferenceLLMProviderValues.OPENAI.value
270
+ self._attributes[LLM_SYSTEM] = OpenInferenceLLMSystemValues.OPENAI.value
258
271
  self.client = AsyncOpenAI(api_key=api_key)
259
272
  self.model_name = model.name
260
273
  self.rate_limiter = PlaygroundRateLimiter(model.provider_key, OpenAIRateLimitError)
@@ -335,7 +348,7 @@ class OpenAIStreamingClient(PlaygroundStreamingClient):
335
348
  openai_messages = [self.to_openai_chat_completion_param(*message) for message in messages]
336
349
  tool_call_ids: dict[int, str] = {}
337
350
  token_usage: Optional["CompletionUsage"] = None
338
- throttled_create = self.rate_limiter.alimit(self.client.chat.completions.create)
351
+ throttled_create = self.rate_limiter._alimit(self.client.chat.completions.create)
339
352
  async for chunk in await throttled_create(
340
353
  messages=openai_messages,
341
354
  model=self.model_name,
@@ -504,7 +517,7 @@ class OpenAIO1StreamingClient(OpenAIStreamingClient):
504
517
 
505
518
  tool_call_ids: dict[int, str] = {}
506
519
 
507
- throttled_create = self.rate_limiter.alimit(self.client.chat.completions.create)
520
+ throttled_create = self.rate_limiter._alimit(self.client.chat.completions.create)
508
521
  response = await throttled_create(
509
522
  messages=openai_messages,
510
523
  model=self.model_name,
@@ -610,12 +623,16 @@ class AzureOpenAIStreamingClient(OpenAIStreamingClient):
610
623
  from openai import AsyncAzureOpenAI
611
624
 
612
625
  super().__init__(model=model, api_key=api_key)
613
- if model.endpoint is None or model.api_version is None:
614
- raise ValueError("endpoint and api_version are required for Azure OpenAI models")
626
+ self._attributes[LLM_PROVIDER] = OpenInferenceLLMProviderValues.AZURE.value
627
+ self._attributes[LLM_SYSTEM] = OpenInferenceLLMSystemValues.OPENAI.value
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")
615
632
  self.client = AsyncAzureOpenAI(
616
633
  api_key=api_key,
617
- azure_endpoint=model.endpoint,
618
- api_version=model.api_version,
634
+ azure_endpoint=endpoint,
635
+ api_version=api_version,
619
636
  )
620
637
 
621
638
 
@@ -638,6 +655,10 @@ class AnthropicStreamingClient(PlaygroundStreamingClient):
638
655
  import anthropic
639
656
 
640
657
  super().__init__(model=model, api_key=api_key)
658
+ self._attributes[LLM_PROVIDER] = OpenInferenceLLMProviderValues.ANTHROPIC.value
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")
641
662
  self.client = anthropic.AsyncAnthropic(api_key=api_key)
642
663
  self.model_name = model.name
643
664
  self.rate_limiter = PlaygroundRateLimiter(model.provider_key, anthropic.RateLimitError)
@@ -693,12 +714,10 @@ class AnthropicStreamingClient(PlaygroundStreamingClient):
693
714
  import anthropic.types as anthropic_types
694
715
 
695
716
  anthropic_messages, system_prompt = self._build_anthropic_messages(messages)
696
-
697
717
  anthropic_params = {
698
718
  "messages": anthropic_messages,
699
719
  "model": self.model_name,
700
720
  "system": system_prompt,
701
- "max_tokens": 1024,
702
721
  "tools": tools,
703
722
  **invocation_parameters,
704
723
  }
@@ -751,19 +770,44 @@ class AnthropicStreamingClient(PlaygroundStreamingClient):
751
770
  anthropic_messages: list["MessageParam"] = []
752
771
  system_prompt = ""
753
772
  for role, content, _tool_call_id, _tool_calls in messages:
773
+ tool_aware_content = self._anthropic_message_content(content, _tool_calls)
754
774
  if role == ChatCompletionMessageRole.USER:
755
- anthropic_messages.append({"role": "user", "content": content})
775
+ anthropic_messages.append({"role": "user", "content": tool_aware_content})
756
776
  elif role == ChatCompletionMessageRole.AI:
757
- anthropic_messages.append({"role": "assistant", "content": content})
777
+ anthropic_messages.append({"role": "assistant", "content": tool_aware_content})
758
778
  elif role == ChatCompletionMessageRole.SYSTEM:
759
779
  system_prompt += content + "\n"
760
780
  elif role == ChatCompletionMessageRole.TOOL:
761
- raise NotImplementedError
781
+ anthropic_messages.append(
782
+ {
783
+ "role": "user",
784
+ "content": [
785
+ {
786
+ "type": "tool_result",
787
+ "tool_use_id": _tool_call_id or "",
788
+ "content": content or "",
789
+ }
790
+ ],
791
+ }
792
+ )
762
793
  else:
763
794
  assert_never(role)
764
795
 
765
796
  return anthropic_messages, system_prompt
766
797
 
798
+ def _anthropic_message_content(
799
+ self, content: str, tool_calls: Optional[list[JSONScalarType]]
800
+ ) -> Union[str, list[Union["ToolResultBlockParam", "TextBlockParam"]]]:
801
+ if tool_calls:
802
+ # Anthropic combines tool calls and the reasoning text into a single message object
803
+ tool_use_content: list[Union["ToolResultBlockParam", "TextBlockParam"]] = []
804
+ if content:
805
+ tool_use_content.append({"type": "text", "text": content})
806
+ tool_use_content.extend(tool_calls)
807
+ return tool_use_content
808
+
809
+ return content
810
+
767
811
 
768
812
  @register_llm_client(
769
813
  provider_key=GenerativeProviderKey.GEMINI,
@@ -784,6 +828,14 @@ class GeminiStreamingClient(PlaygroundStreamingClient):
784
828
  import google.generativeai as google_genai
785
829
 
786
830
  super().__init__(model=model, api_key=api_key)
831
+ self._attributes[LLM_PROVIDER] = OpenInferenceLLMProviderValues.GOOGLE.value
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")
787
839
  google_genai.configure(api_key=api_key)
788
840
  self.model_name = model.name
789
841
 
@@ -905,6 +957,8 @@ def initialize_playground_clients() -> None:
905
957
  pass
906
958
 
907
959
 
960
+ LLM_PROVIDER = SpanAttributes.LLM_PROVIDER
961
+ LLM_SYSTEM = SpanAttributes.LLM_SYSTEM
908
962
  LLM_TOKEN_COUNT_PROMPT = SpanAttributes.LLM_TOKEN_COUNT_PROMPT
909
963
  LLM_TOKEN_COUNT_COMPLETION = SpanAttributes.LLM_TOKEN_COUNT_COMPLETION
910
964
  LLM_TOKEN_COUNT_TOTAL = SpanAttributes.LLM_TOKEN_COUNT_TOTAL
@@ -330,20 +330,45 @@ def llm_input_messages(
330
330
  tuple[ChatCompletionMessageRole, str, Optional[str], Optional[list[JSONScalarType]]]
331
331
  ],
332
332
  ) -> Iterator[tuple[str, Any]]:
333
- for i, (role, content, _tool_call_id, tool_calls) in enumerate(messages):
333
+ for i, (role, content, tool_call_id, tool_calls) in enumerate(messages):
334
334
  yield f"{LLM_INPUT_MESSAGES}.{i}.{MESSAGE_ROLE}", role.value.lower()
335
335
  yield f"{LLM_INPUT_MESSAGES}.{i}.{MESSAGE_CONTENT}", content
336
+ if role == ChatCompletionMessageRole.TOOL and tool_call_id:
337
+ # Anthropic tool result spans
338
+ yield f"{LLM_INPUT_MESSAGES}.{i}.{MESSAGE_TOOL_CALL_ID}", tool_call_id
339
+
336
340
  if tool_calls is not None:
337
341
  for tool_call_index, tool_call in enumerate(tool_calls):
338
- yield (
339
- f"{LLM_INPUT_MESSAGES}.{i}.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_FUNCTION_NAME}",
340
- tool_call["function"]["name"],
341
- )
342
- if arguments := tool_call["function"]["arguments"]:
342
+ if tool_call.get("type") == "tool_use":
343
+ # Anthropic tool call spans
344
+ yield (
345
+ f"{LLM_INPUT_MESSAGES}.{i}.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_FUNCTION_NAME}",
346
+ tool_call["name"],
347
+ )
343
348
  yield (
344
349
  f"{LLM_INPUT_MESSAGES}.{i}.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_FUNCTION_ARGUMENTS_JSON}",
345
- safe_json_dumps(jsonify(arguments)),
350
+ safe_json_dumps(jsonify(tool_call["input"])),
351
+ )
352
+ yield (
353
+ f"{LLM_INPUT_MESSAGES}.{i}.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_ID}",
354
+ tool_call["id"],
346
355
  )
356
+ elif tool_call_function := tool_call.get("function"):
357
+ # OpenAI tool call spans
358
+ yield (
359
+ f"{LLM_INPUT_MESSAGES}.{i}.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_FUNCTION_NAME}",
360
+ tool_call_function["name"],
361
+ )
362
+ if arguments := tool_call_function["arguments"]:
363
+ yield (
364
+ f"{LLM_INPUT_MESSAGES}.{i}.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_FUNCTION_ARGUMENTS_JSON}",
365
+ safe_json_dumps(jsonify(arguments)),
366
+ )
367
+ if tool_call_id := tool_call.get("id"):
368
+ yield (
369
+ f"{LLM_INPUT_MESSAGES}.{i}.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_ID}",
370
+ tool_call_id,
371
+ )
347
372
 
348
373
 
349
374
  def _llm_output_messages(
@@ -354,6 +379,11 @@ def _llm_output_messages(
354
379
  if content := "".join(chunk.content for chunk in text_chunks):
355
380
  yield f"{LLM_OUTPUT_MESSAGES}.0.{MESSAGE_CONTENT}", content
356
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
+ )
357
387
  if tool_call_chunks_ and (name := tool_call_chunks_[0].function.name):
358
388
  yield (
359
389
  f"{LLM_OUTPUT_MESSAGES}.0.{MESSAGE_TOOL_CALLS}.{tool_call_index}.{TOOL_CALL_FUNCTION_NAME}",
@@ -416,7 +446,9 @@ MESSAGE_CONTENT = MessageAttributes.MESSAGE_CONTENT
416
446
  MESSAGE_ROLE = MessageAttributes.MESSAGE_ROLE
417
447
  MESSAGE_TOOL_CALLS = MessageAttributes.MESSAGE_TOOL_CALLS
418
448
 
449
+ TOOL_CALL_ID = ToolCallAttributes.TOOL_CALL_ID
419
450
  TOOL_CALL_FUNCTION_NAME = ToolCallAttributes.TOOL_CALL_FUNCTION_NAME
420
451
  TOOL_CALL_FUNCTION_ARGUMENTS_JSON = ToolCallAttributes.TOOL_CALL_FUNCTION_ARGUMENTS_JSON
421
-
452
+ TOOL_CALL_ID = ToolCallAttributes.TOOL_CALL_ID
453
+ MESSAGE_TOOL_CALL_ID = MessageAttributes.MESSAGE_TOOL_CALL_ID
422
454
  TOOL_JSON_SCHEMA = ToolAttributes.TOOL_JSON_SCHEMA
@@ -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"No LLM client registered for provider '{provider_key}'")
131
- llm_client = llm_client_class(
132
- model=input.model,
133
- api_key=input.api_key,
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
- results = await asyncio.gather(
186
- *(
187
- cls._chat_completion(
188
- info,
189
- llm_client,
190
- ChatCompletionInput(
191
- model=input.model,
192
- api_key=input.api_key,
193
- messages=input.messages,
194
- tools=input.tools,
195
- invocation_parameters=input.invocation_parameters,
196
- template=TemplateOptions(
197
- language=input.template_language,
198
- variables=revision.input,
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
- for revision in revisions
203
- ),
204
- return_exceptions=True,
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"No LLM client registered for provider '{provider_key}'")
270
- llm_client = llm_client_class(
271
- model=input.model,
272
- api_key=input.api_key,
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