arize-phoenix 11.35.0__py3-none-any.whl → 11.37.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of arize-phoenix might be problematic. Click here for more details.

Files changed (23) hide show
  1. {arize_phoenix-11.35.0.dist-info → arize_phoenix-11.37.0.dist-info}/METADATA +1 -1
  2. {arize_phoenix-11.35.0.dist-info → arize_phoenix-11.37.0.dist-info}/RECORD +22 -22
  3. phoenix/server/api/helpers/playground_clients.py +39 -3
  4. phoenix/server/api/input_types/GenerativeModelInput.py +3 -0
  5. phoenix/server/api/input_types/SpanSort.py +1 -1
  6. phoenix/server/api/types/Experiment.py +2 -0
  7. phoenix/server/api/types/Project.py +9 -5
  8. phoenix/server/api/types/pagination.py +11 -2
  9. phoenix/server/static/.vite/manifest.json +39 -39
  10. phoenix/server/static/assets/{components-CdQiQTvs.js → components-CFzdBkk_.js} +572 -363
  11. phoenix/server/static/assets/{index-B1VuXYRI.js → index-DayUA9lQ.js} +12 -2
  12. phoenix/server/static/assets/{pages-CnfZ3RhB.js → pages-CvUhOO9h.js} +528 -497
  13. phoenix/server/static/assets/{vendor-Cfrr9FCF.js → vendor-BdjZxMii.js} +186 -186
  14. phoenix/server/static/assets/vendor-arizeai-CHYlS8jV.js +165 -0
  15. phoenix/server/static/assets/{vendor-codemirror-ClqtONZQ.js → vendor-codemirror-Di6t4HnH.js} +3 -3
  16. phoenix/server/static/assets/{vendor-recharts-D6kvOpmb.js → vendor-recharts-C9wCDYj3.js} +4 -4
  17. phoenix/server/static/assets/{vendor-shiki-xSOiKxt0.js → vendor-shiki-MNnmOotP.js} +1 -1
  18. phoenix/version.py +1 -1
  19. phoenix/server/static/assets/vendor-arizeai-Dz0kN-lQ.js +0 -168
  20. {arize_phoenix-11.35.0.dist-info → arize_phoenix-11.37.0.dist-info}/WHEEL +0 -0
  21. {arize_phoenix-11.35.0.dist-info → arize_phoenix-11.37.0.dist-info}/entry_points.txt +0 -0
  22. {arize_phoenix-11.35.0.dist-info → arize_phoenix-11.37.0.dist-info}/licenses/IP_NOTICE +0 -0
  23. {arize_phoenix-11.35.0.dist-info → arize_phoenix-11.37.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arize-phoenix
3
- Version: 11.35.0
3
+ Version: 11.37.0
4
4
  Summary: AI Observability and Evaluation
5
5
  Project-URL: Documentation, https://arize.com/docs/phoenix/
6
6
  Project-URL: Issues, https://github.com/Arize-ai/phoenix/issues
@@ -6,7 +6,7 @@ phoenix/exceptions.py,sha256=n2L2KKuecrdflB9MsCdAYCiSEvGJptIsfRkXMoJle7A,169
6
6
  phoenix/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
7
7
  phoenix/services.py,sha256=ngkyKGVatX3cO2WJdo2hKdaVKP-xJCMvqthvga6kJss,5196
8
8
  phoenix/settings.py,sha256=2kHfT3BNOVd4dAO1bq-syEQbHSG8oX2-7NhOwK2QREk,896
9
- phoenix/version.py,sha256=RJFnwmqSmKmJQDpkbU6omf53SgvFxHMmwQOK75tvJYM,24
9
+ phoenix/version.py,sha256=51ny777jKy9SIcIn2Vr7pZhCjHVXPehMhak2EG9U07g,24
10
10
  phoenix/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  phoenix/core/embedding_dimension.py,sha256=zKGbcvwOXgLf-yrJBpQyKtd-LEOPRKHnUToyAU8Owis,87
12
12
  phoenix/core/model.py,sha256=qBFraOtmwCCnWJltKNP18DDG0mULXigytlFsa6YOz6k,4837
@@ -183,7 +183,7 @@ phoenix/server/api/helpers/__init__.py,sha256=m2-xaSPqUiSs91k62JaRDjFNfl-1byxBfY
183
183
  phoenix/server/api/helpers/annotations.py,sha256=9gMXKpMTfWEChoSCnvdWYuyB0hlSnNOp-qUdar9Vono,262
184
184
  phoenix/server/api/helpers/dataset_helpers.py,sha256=3bdGBoUzqrtg-sr5p2wpQLOU6dhg_3TKFHNeJj8p0TU,9155
185
185
  phoenix/server/api/helpers/experiment_run_filters.py,sha256=DOnVwrmn39eAkk2mwuZP8kIcAnR5jrOgllEwWSjsw94,29893
186
- phoenix/server/api/helpers/playground_clients.py,sha256=fG97GnJPxOYMd0lNHdQfML_ZmSZfLnY2s7_GAiAecOc,72327
186
+ phoenix/server/api/helpers/playground_clients.py,sha256=7PuGc5s9uKZjM6uGO85yc0F0HWke3Yn1F6N3dBaukOY,73757
187
187
  phoenix/server/api/helpers/playground_registry.py,sha256=n0v4-KnvZJxeaEwOla5qBbnOQjSWznKmMhZnh9ziJt0,2584
188
188
  phoenix/server/api/helpers/playground_spans.py,sha256=QpXwPl_fFNwm_iA1A77XApUyXMl1aDmonw8aXuNZ_4k,17132
189
189
  phoenix/server/api/helpers/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -215,7 +215,7 @@ phoenix/server/api/input_types/DeleteExperimentsInput.py,sha256=4d9N0vSLYbuysAam
215
215
  phoenix/server/api/input_types/DimensionFilter.py,sha256=eBYcn7ECSJQlEePvbStqkHBRicbIL4vEAzFJwX7bacQ,3137
216
216
  phoenix/server/api/input_types/DimensionInput.py,sha256=Vfx5FmiMKey4-EHDQsQRPzSAMRJMN5oVMLDUl4NKAa8,164
217
217
  phoenix/server/api/input_types/GenerativeCredentialInput.py,sha256=sEM9UtgDMMuhImLwGXctD8BWDs2V3hNQ1mosoklRZvc,219
218
- phoenix/server/api/input_types/GenerativeModelInput.py,sha256=ceJ65f7Mf1JmOuH9TV3KJYbNnQ-_Z85Dl4_vPMB1K_o,713
218
+ phoenix/server/api/input_types/GenerativeModelInput.py,sha256=M9R5LmLjyxOYPEIiann4ln23degOWJ2GTIk64bi73yI,841
219
219
  phoenix/server/api/input_types/Granularity.py,sha256=dbBlD_GsIBa8_xrx4JlLuR59bQ0NRB5H-cv1zvcb-cw,2299
220
220
  phoenix/server/api/input_types/InvocationParameters.py,sha256=62xL0iIKvuQherkuJaJ6Lha4TTEoYLpvH-pEP9awK6k,5260
221
221
  phoenix/server/api/input_types/PatchAnnotationInput.py,sha256=2wxC-ibQU59I28amTxLMYMo9SSvJwAIor0w0YvS0e48,676
@@ -230,7 +230,7 @@ phoenix/server/api/input_types/PromptTemplateOptions.py,sha256=8ZJdH1F9fExcdH9dF
230
230
  phoenix/server/api/input_types/PromptVersionInput.py,sha256=6iFWf2Ye9K1dwL1810L-wUTLkMtOIHemJTxar4xF4kw,3911
231
231
  phoenix/server/api/input_types/SpanAnnotationFilter.py,sha256=-djfIXYCxV6sV3GPOZQUV0SPfiWDhRlTORfeQ7tCBgQ,2671
232
232
  phoenix/server/api/input_types/SpanAnnotationSort.py,sha256=T5pAGzmh4MiJp9JMAzNDByFVTczfw02FH4WFWwFezyI,361
233
- phoenix/server/api/input_types/SpanSort.py,sha256=GReQx9yOo0Kehi2y4AtY69aZhRtcqvcg-9bSIFru69U,7540
233
+ phoenix/server/api/input_types/SpanSort.py,sha256=1AHrqx3HuVKsp9DSaDsQMAyid4Au3kqY38mE9x0nPBU,7552
234
234
  phoenix/server/api/input_types/TimeBinConfig.py,sha256=s4p0SNTGRY6rbHfZhEMwmon5zX85j-DbN06GkapF6jg,516
235
235
  phoenix/server/api/input_types/TimeRange.py,sha256=pwhC2jx6dFIgT0qFfnO68qiJp9-m7Je5QkNscNsuVxA,700
236
236
  phoenix/server/api/input_types/TraceAnnotationSort.py,sha256=BzwiUnMh2VsgQYnhDlbJ6ljHugqIS4YDUlYzvq_tl3o,365
@@ -311,7 +311,7 @@ phoenix/server/api/types/EvaluationSummary.py,sha256=vILYejnfPvMwWEXOwhQZsANvYe3
311
311
  phoenix/server/api/types/Event.py,sha256=iYt_Jx1Roioo0vZ0iPeJTHcTu6NSm4ilVMJ-IMUHAKk,3970
312
312
  phoenix/server/api/types/EventMetadata.py,sha256=-J0tYF9eZTHwCjwxQHY7Gckr2_MNW5OoWT1mydweZNM,635
313
313
  phoenix/server/api/types/ExampleRevisionInterface.py,sha256=gV3Gt9-3Oi5wjaVtepC6nOt3FzTzZFD1KebNnqiw56E,294
314
- phoenix/server/api/types/Experiment.py,sha256=URdD3Ow0gTlJRd74duLdGFs-E3gKy2-UAah1AIaFKGk,8230
314
+ phoenix/server/api/types/Experiment.py,sha256=GdTAS-p5d1GyekwGItQZClHS1Hz1u9IfTcnAeZUaCwU,8295
315
315
  phoenix/server/api/types/ExperimentAnnotationSummary.py,sha256=Uk3JtxIrsMoZT5tqc4nJdUOM3XegVzjUyoV3pkjNotE,256
316
316
  phoenix/server/api/types/ExperimentComparison.py,sha256=fj4KoAPFNJvfrHBMloGkHz_-7Lf403IMe0OwDDJyZWk,383
317
317
  phoenix/server/api/types/ExperimentRepeatedRunGroup.py,sha256=a2-C6ZWyFm-THvus6n4WDYGtmapm-ZWFaDahW7A2i28,5434
@@ -332,7 +332,7 @@ phoenix/server/api/types/ModelInterface.py,sha256=Qe7H23wDb_Q2-HmeY2t0R5Jsn4aAfY
332
332
  phoenix/server/api/types/NumericRange.py,sha256=afEjgF97Go_OvmjMggbPBt-zGM8IONewAyEiKEHRds0,192
333
333
  phoenix/server/api/types/PerformanceMetric.py,sha256=KFkmJDqP43eDUtARQOUqR7NYcxvL6Vh2uisHWU6H3ko,387
334
334
  phoenix/server/api/types/PlaygroundModel.py,sha256=IqJFxsAAJMRyaFI9ryI3GQrpFOJ5Llf6kIutEO-tFvM,321
335
- phoenix/server/api/types/Project.py,sha256=XJUVEGCmEgToIyoVNWpNgcgtV1g24DvAKzFHpDNpCJY,72020
335
+ phoenix/server/api/types/Project.py,sha256=klaowPuWXVz6tFQEA10gL1pY554H-nPFNtLcUSGGMxk,72289
336
336
  phoenix/server/api/types/ProjectSession.py,sha256=uwqTsDTfSGz13AvP-cwS_mJR5JZ1lHqu10ungbl7g5s,6245
337
337
  phoenix/server/api/types/ProjectTraceRetentionPolicy.py,sha256=tYy2kgalPDyuaYZr0VUHjH0YpXaiF_QOzg5yfaV_c7c,3782
338
338
  phoenix/server/api/types/Prompt.py,sha256=ad52KVQ1yJrAWXd3HdOKKHzyaUJqrp2mtFEe1QGEE4E,5455
@@ -368,7 +368,7 @@ phoenix/server/api/types/ValidationResult.py,sha256=pHwdYk4J7SJ5xhlWWHg_6qWkfk4r
368
368
  phoenix/server/api/types/VectorDriftMetricEnum.py,sha256=etiJM5ZjQuD-oE7sY-FbdIKY050jk3IU49IMwmfJbEc,188
369
369
  phoenix/server/api/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
370
370
  phoenix/server/api/types/node.py,sha256=ya1kJz6ok0LEiMMJOvV6s6nr_biWBZWAiC9JEtR-ki8,1073
371
- phoenix/server/api/types/pagination.py,sha256=BXm46gXZfrBS4hpiLvVSEdsbb29ctUMVJYjKXlOLxUA,9064
371
+ phoenix/server/api/types/pagination.py,sha256=GJktCIGRfbuFh8kHJzJ0QTzs6ZDtAJizgjSSObnBCeM,9342
372
372
  phoenix/server/cost_tracking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
373
373
  phoenix/server/cost_tracking/cost_details_calculator.py,sha256=Tt0YcuLhgPuXKWJemWVmYQfG0xQUvH4VziIj6KcDnoA,8945
374
374
  phoenix/server/cost_tracking/cost_model_lookup.py,sha256=jhtVdnQBzrTUHeOGPWgOebk-Io5hpJ1vAgWOu8ojeJ4,6801
@@ -402,16 +402,16 @@ phoenix/server/static/apple-touch-icon-76x76.png,sha256=CT_xT12I0u2i0WU8JzBZBuOQ
402
402
  phoenix/server/static/apple-touch-icon.png,sha256=fOfpjqGpWYbJ0eAurKsyoZP1EAs6ZVooBJ_SGk2ZkDs,3801
403
403
  phoenix/server/static/favicon.ico,sha256=bY0vvCKRftemZfPShwZtE93DiiQdaYaozkPGwNFr6H8,34494
404
404
  phoenix/server/static/modernizr.js,sha256=mvK-XtkNqjOral-QvzoqsyOMECXIMu5BQwSVN_wcU9c,2564
405
- phoenix/server/static/.vite/manifest.json,sha256=UKiCtA5rvKMr8U4zLFRXo5S5Fdvy8dKouD1kF3GESko,2328
406
- phoenix/server/static/assets/components-CdQiQTvs.js,sha256=ffg4jmfz-Bc9PTLXXAz7OduRazQDl5KZyeR_3S2aILs,675981
407
- phoenix/server/static/assets/index-B1VuXYRI.js,sha256=jOk_qo0Q0SRXWfvHVlValebC3vs1mUfV1v-Kf94B2rc,62934
408
- phoenix/server/static/assets/pages-CnfZ3RhB.js,sha256=XYLansUm9qmewwVwsW-dskFdfP72RCMzRAdzlLMJMhg,1298004
405
+ phoenix/server/static/.vite/manifest.json,sha256=eL7fSMB_ukWrI1_haVcKcon1yQTo89vwyOJmSZar_qU,2328
406
+ phoenix/server/static/assets/components-CFzdBkk_.js,sha256=TPy0Mz14mPKzLVdxczNBA9dAvPE9TkdOZBMu8xkJqMY,683709
407
+ phoenix/server/static/assets/index-DayUA9lQ.js,sha256=4QQWs2ubciFLQwVnRPTRHZkzTCW_HGvtNjJfVcbi-pI,63435
408
+ phoenix/server/static/assets/pages-CvUhOO9h.js,sha256=x30rhunnQtnuzZnX-HArUNQ-Uii4sdsL8tFFmoWEjsg,1303234
409
409
  phoenix/server/static/assets/vendor-BGzfc4EU.css,sha256=Nx5Lmx-bqYR7nsO_O4kEBcrJ8cwknWjZ6seHN3_s4UQ,3171
410
- phoenix/server/static/assets/vendor-Cfrr9FCF.js,sha256=e5sXxTzHgKwjsNy7bFWp19fM9QolSJBQ9FvE4hmxrPs,2575393
411
- phoenix/server/static/assets/vendor-arizeai-Dz0kN-lQ.js,sha256=hPa1rpMUjztQaAsf5h87E_RCDhcuWowkoTrfMaTS5_g,121519
412
- phoenix/server/static/assets/vendor-codemirror-ClqtONZQ.js,sha256=zPD9V1TJW7mlnmIQcpjjaajHLATsDb0dxXnGsq24Qcg,413205
413
- phoenix/server/static/assets/vendor-recharts-D6kvOpmb.js,sha256=AcaZOFH-ggGi-znCeAP_b072ALbIcPqhqYDZn63Hjps,231653
414
- phoenix/server/static/assets/vendor-shiki-xSOiKxt0.js,sha256=itTnSRR18G_YLCygdVlLLqMrXHaPqjnD2Z6WcS4O9ro,305160
410
+ phoenix/server/static/assets/vendor-BdjZxMii.js,sha256=CEEWyhdR8PcZfr9EntiJVBEN3hoFmS3hnvxQapcB57M,2591438
411
+ phoenix/server/static/assets/vendor-arizeai-CHYlS8jV.js,sha256=AEKxh9WhnE-QrWus26WBBR0Fq1fh2r1iXPl3BFU7quk,112652
412
+ phoenix/server/static/assets/vendor-codemirror-Di6t4HnH.js,sha256=4grodwIcHPZTnaKyCM8LqhYr7xQh6sQfICc-eQ_5l2c,413213
413
+ phoenix/server/static/assets/vendor-recharts-C9wCDYj3.js,sha256=_vwHqxWoiaeY2yKMKGQxyb62QorGUX0Y9kv-jE0JAMA,231654
414
+ phoenix/server/static/assets/vendor-shiki-MNnmOotP.js,sha256=gXLCqndUHWJUssTPN2s4nOnxBMlnGyWb2XmIwogQfLs,305160
415
415
  phoenix/server/static/assets/vendor-three-BLWp5bic.js,sha256=vfSCVXS20jA0Ceo_O0mDxYBcROinWMdPE6RR4JXmtec,620972
416
416
  phoenix/server/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
417
417
  phoenix/server/templates/index.html,sha256=QAYh0TG5mg-GvDQUR09aD9ebl9Sfq0fYAcfIa5G7J6E,7148
@@ -451,9 +451,9 @@ phoenix/utilities/project.py,sha256=auVpARXkDb-JgeX5f2aStyFIkeKvGwN9l7qrFeJMVxI,
451
451
  phoenix/utilities/re.py,sha256=6YyUWIkv0zc2SigsxfOWIHzdpjKA_TZo2iqKq7zJKvw,2081
452
452
  phoenix/utilities/span_store.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
453
453
  phoenix/utilities/template_formatters.py,sha256=gh9PJD6WEGw7TEYXfSst1UR4pWWwmjxMLrDVQ_CkpkQ,2779
454
- arize_phoenix-11.35.0.dist-info/METADATA,sha256=xS7hzRKWSqDhACjwfYoslteLqm7z6LzDigKI74ei-rg,34045
455
- arize_phoenix-11.35.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
456
- arize_phoenix-11.35.0.dist-info/entry_points.txt,sha256=Pgpn8Upxx9P8z8joPXZWl2LlnAlGc3gcQoVchb06X1Q,94
457
- arize_phoenix-11.35.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
458
- arize_phoenix-11.35.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
459
- arize_phoenix-11.35.0.dist-info/RECORD,,
454
+ arize_phoenix-11.37.0.dist-info/METADATA,sha256=1taqXAi5gQonzOQVvGR3ibHNHhjlVTXK-hptSPCpL8M,34045
455
+ arize_phoenix-11.37.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
456
+ arize_phoenix-11.37.0.dist-info/entry_points.txt,sha256=Pgpn8Upxx9P8z8joPXZWl2LlnAlGc3gcQoVchb06X1Q,94
457
+ arize_phoenix-11.37.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
458
+ arize_phoenix-11.37.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
459
+ arize_phoenix-11.37.0.dist-info/RECORD,,
@@ -57,6 +57,7 @@ from phoenix.server.api.types.GenerativeProvider import GenerativeProviderKey
57
57
  if TYPE_CHECKING:
58
58
  import httpx
59
59
  from anthropic.types import MessageParam, TextBlockParam, ToolResultBlockParam
60
+ from botocore.awsrequest import AWSPreparedRequest # type: ignore[import-untyped]
60
61
  from google.generativeai.types import ContentType
61
62
  from openai import AsyncAzureOpenAI, AsyncOpenAI
62
63
  from openai.types import CompletionUsage
@@ -546,6 +547,7 @@ class DeepSeekStreamingClient(OpenAIBaseStreamingClient):
546
547
  client = AsyncOpenAI(
547
548
  api_key=api_key,
548
549
  base_url=base_url or "https://api.deepseek.com",
550
+ default_headers=model.custom_headers or None,
549
551
  )
550
552
  super().__init__(client=client, model=model, credentials=credentials)
551
553
  # DeepSeek uses OpenAI-compatible API but we'll track it as a separate provider
@@ -587,6 +589,7 @@ class XAIStreamingClient(OpenAIBaseStreamingClient):
587
589
  client = AsyncOpenAI(
588
590
  api_key=api_key,
589
591
  base_url=base_url or "https://api.x.ai/v1",
592
+ default_headers=model.custom_headers or None,
590
593
  )
591
594
  super().__init__(client=client, model=model, credentials=credentials)
592
595
  # xAI uses OpenAI-compatible API but we'll track it as a separate provider
@@ -624,7 +627,11 @@ class OllamaStreamingClient(OpenAIBaseStreamingClient):
624
627
  if not base_url:
625
628
  raise BadRequest("An Ollama base URL is required for Ollama models")
626
629
  api_key = "ollama"
627
- client = AsyncOpenAI(api_key=api_key, base_url=base_url)
630
+ client = AsyncOpenAI(
631
+ api_key=api_key,
632
+ base_url=base_url,
633
+ default_headers=model.custom_headers or None,
634
+ )
628
635
  super().__init__(client=client, model=model, credentials=credentials)
629
636
  # Ollama uses OpenAI-compatible API but we'll track it as a separate provider
630
637
  # Adding a custom "ollama" provider value to make it distinguishable in traces
@@ -679,6 +686,7 @@ class BedrockStreamingClient(PlaygroundStreamingClient):
679
686
  super().__init__(model=model, credentials=credentials)
680
687
  self.region = model.region or "us-east-1"
681
688
  self.api = "converse"
689
+ self.custom_headers = model.custom_headers or {}
682
690
  self.aws_access_key_id = _get_credential_value(credentials, "AWS_ACCESS_KEY_ID") or getenv(
683
691
  "AWS_ACCESS_KEY_ID"
684
692
  )
@@ -697,9 +705,24 @@ class BedrockStreamingClient(PlaygroundStreamingClient):
697
705
  aws_session_token=self.aws_session_token,
698
706
  )
699
707
 
708
+ # Add custom headers support via boto3 event system
709
+ if self.custom_headers:
710
+ self._setup_custom_headers(self.client, self.custom_headers)
711
+
700
712
  self._attributes[LLM_PROVIDER] = "aws"
701
713
  self._attributes[LLM_SYSTEM] = "aws"
702
714
 
715
+ @staticmethod
716
+ def _setup_custom_headers(client: Any, custom_headers: Mapping[str, str]) -> None:
717
+ """Setup custom headers using boto3's event system."""
718
+ if not custom_headers:
719
+ return
720
+
721
+ def add_custom_headers(request: "AWSPreparedRequest", **kwargs: Any) -> None:
722
+ request.headers.update(custom_headers)
723
+
724
+ client.meta.events.register("before-send.*", add_custom_headers)
725
+
703
726
  @classmethod
704
727
  def dependencies(cls) -> list[Dependency]:
705
728
  return [Dependency(name="boto3")]
@@ -756,6 +779,9 @@ class BedrockStreamingClient(PlaygroundStreamingClient):
756
779
  aws_secret_access_key=self.aws_secret_access_key,
757
780
  aws_session_token=self.aws_session_token,
758
781
  )
782
+ # Re-setup custom headers for the new client
783
+ if self.custom_headers:
784
+ self._setup_custom_headers(self.client, self.custom_headers)
759
785
  if self.api == "invoke":
760
786
  async for chunk in self._handle_invoke_api(messages, tools, invocation_parameters):
761
787
  yield chunk
@@ -1140,7 +1166,12 @@ class OpenAIStreamingClient(OpenAIBaseStreamingClient):
1140
1166
  raise BadRequest("An API key is required for OpenAI models")
1141
1167
  api_key = "sk-fake-api-key"
1142
1168
 
1143
- client = AsyncOpenAI(api_key=api_key, base_url=base_url, timeout=30)
1169
+ client = AsyncOpenAI(
1170
+ api_key=api_key,
1171
+ base_url=base_url,
1172
+ default_headers=model.custom_headers or None,
1173
+ timeout=30,
1174
+ )
1144
1175
  super().__init__(client=client, model=model, credentials=credentials)
1145
1176
  self._attributes[LLM_PROVIDER] = OpenInferenceLLMProviderValues.OPENAI.value
1146
1177
  self._attributes[LLM_SYSTEM] = OpenInferenceLLMSystemValues.OPENAI.value
@@ -1295,6 +1326,7 @@ class AzureOpenAIStreamingClient(OpenAIBaseStreamingClient):
1295
1326
  api_key=api_key,
1296
1327
  azure_endpoint=endpoint,
1297
1328
  api_version=api_version,
1329
+ default_headers=model.custom_headers or None,
1298
1330
  )
1299
1331
  else:
1300
1332
  try:
@@ -1312,6 +1344,7 @@ class AzureOpenAIStreamingClient(OpenAIBaseStreamingClient):
1312
1344
  ),
1313
1345
  azure_endpoint=endpoint,
1314
1346
  api_version=api_version,
1347
+ default_headers=model.custom_headers or None,
1315
1348
  )
1316
1349
  super().__init__(client=client, model=model, credentials=credentials)
1317
1350
  self._attributes[LLM_PROVIDER] = OpenInferenceLLMProviderValues.AZURE.value
@@ -1459,7 +1492,10 @@ class AnthropicStreamingClient(PlaygroundStreamingClient):
1459
1492
  if not api_key:
1460
1493
  raise BadRequest("An API key is required for Anthropic models")
1461
1494
 
1462
- self.client = anthropic.AsyncAnthropic(api_key=api_key)
1495
+ self.client = anthropic.AsyncAnthropic(
1496
+ api_key=api_key,
1497
+ default_headers=model.custom_headers or None,
1498
+ )
1463
1499
  self.model_name = model.name
1464
1500
  self.rate_limiter = PlaygroundRateLimiter(model.provider_key, anthropic.RateLimitError)
1465
1501
  self.client._client = _HttpxClient(self.client._client, self._attributes)
@@ -2,6 +2,7 @@ from typing import Optional
2
2
 
3
3
  import strawberry
4
4
  from strawberry import UNSET
5
+ from strawberry.scalars import JSON
5
6
 
6
7
  from phoenix.server.api.types.GenerativeProvider import GenerativeProviderKey
7
8
 
@@ -19,3 +20,5 @@ class GenerativeModelInput:
19
20
  """ The API version to use for the model. """
20
21
  region: Optional[str] = UNSET
21
22
  """ The region to use for the model. """
23
+ custom_headers: Optional[JSON] = UNSET
24
+ """ Custom headers to use for the model. """
@@ -199,7 +199,7 @@ class SpanSort:
199
199
  models.SpanAnnotation.span_rowid == models.Span.id,
200
200
  models.SpanAnnotation.name == eval_name,
201
201
  ),
202
- ).order_by(expr)
202
+ ).order_by(nulls_last(expr))
203
203
  return SpanSortConfig(
204
204
  stmt=stmt,
205
205
  orm_expression=eval_result_key.attr.orm_expression,
@@ -33,6 +33,7 @@ class Experiment(Node):
33
33
  name: str
34
34
  project_name: Optional[str]
35
35
  description: Optional[str]
36
+ repetitions: int
36
37
  dataset_version_id: GlobalID
37
38
  metadata: JSON
38
39
  created_at: datetime
@@ -210,6 +211,7 @@ def to_gql_experiment(
210
211
  name=experiment.name,
211
212
  project_name=experiment.project_name,
212
213
  description=experiment.description,
214
+ repetitions=experiment.repetitions,
213
215
  dataset_version_id=GlobalID(DatasetVersion.__name__, str(experiment.dataset_version_id)),
214
216
  metadata=experiment.metadata_,
215
217
  created_at=experiment.created_at,
@@ -355,12 +355,16 @@ class Project(Node):
355
355
  if sort_config and cursor.sort_column:
356
356
  sort_column = cursor.sort_column
357
357
  compare = operator.lt if sort_config.dir is SortDir.desc else operator.gt
358
- stmt = stmt.where(
359
- compare(
360
- tuple_(sort_config.orm_expression, models.Span.id),
361
- (sort_column.value, cursor.rowid),
358
+ if sort_column.type is CursorSortColumnDataType.NULL:
359
+ stmt = stmt.where(sort_config.orm_expression.is_(None))
360
+ stmt = stmt.where(compare(models.Span.id, cursor.rowid))
361
+ else:
362
+ stmt = stmt.where(
363
+ compare(
364
+ tuple_(sort_config.orm_expression, models.Span.id),
365
+ (sort_column.value, cursor.rowid),
366
+ )
362
367
  )
363
- )
364
368
  else:
365
369
  stmt = stmt.where(models.Span.id > cursor.rowid)
366
370
  stmt = stmt.order_by(cursor_rowid_column)
@@ -9,7 +9,7 @@ from strawberry.relay.types import Connection, Edge, NodeType, PageInfo
9
9
  from typing_extensions import TypeAlias, assert_never
10
10
 
11
11
  ID: TypeAlias = int
12
- CursorSortColumnValue: TypeAlias = Union[str, int, float, datetime]
12
+ CursorSortColumnValue: TypeAlias = Union[str, int, float, datetime, None]
13
13
 
14
14
  # A type alias for the connection cursor implementation
15
15
  CursorString = str
@@ -19,6 +19,7 @@ CURSOR_PREFIX = "connection:"
19
19
 
20
20
 
21
21
  class CursorSortColumnDataType(Enum):
22
+ NULL = auto()
22
23
  STRING = auto()
23
24
  INT = auto()
24
25
  FLOAT = auto()
@@ -30,6 +31,10 @@ class CursorSortColumn:
30
31
  type: CursorSortColumnDataType
31
32
  value: CursorSortColumnValue
32
33
 
34
+ def __post_init__(self) -> None:
35
+ if self.value is None:
36
+ self.type = CursorSortColumnDataType.NULL
37
+
33
38
  def __str__(self) -> str:
34
39
  if isinstance(self.value, str):
35
40
  return self.value
@@ -37,7 +42,9 @@ class CursorSortColumn:
37
42
  return str(self.value)
38
43
  if isinstance(self.value, datetime):
39
44
  return self.value.isoformat()
40
- assert_never(self.type)
45
+ if self.value is None:
46
+ return ""
47
+ assert_never(self.value)
41
48
 
42
49
  @classmethod
43
50
  def from_string(cls, type: CursorSortColumnDataType, cursor_string: str) -> "CursorSortColumn":
@@ -50,6 +57,8 @@ class CursorSortColumn:
50
57
  value = float(cursor_string)
51
58
  elif type is CursorSortColumnDataType.DATETIME:
52
59
  value = datetime.fromisoformat(cursor_string)
60
+ elif type is CursorSortColumnDataType.NULL:
61
+ value = None
53
62
  else:
54
63
  assert_never(type)
55
64
  return cls(type=type, value=value)
@@ -1,32 +1,32 @@
1
1
  {
2
- "_components-CdQiQTvs.js": {
3
- "file": "assets/components-CdQiQTvs.js",
2
+ "_components-CFzdBkk_.js": {
3
+ "file": "assets/components-CFzdBkk_.js",
4
4
  "name": "components",
5
5
  "imports": [
6
- "_vendor-Cfrr9FCF.js",
7
- "_pages-CnfZ3RhB.js",
8
- "_vendor-arizeai-Dz0kN-lQ.js",
9
- "_vendor-codemirror-ClqtONZQ.js",
6
+ "_vendor-BdjZxMii.js",
7
+ "_vendor-arizeai-CHYlS8jV.js",
8
+ "_pages-CvUhOO9h.js",
9
+ "_vendor-codemirror-Di6t4HnH.js",
10
10
  "_vendor-three-BLWp5bic.js"
11
11
  ]
12
12
  },
13
- "_pages-CnfZ3RhB.js": {
14
- "file": "assets/pages-CnfZ3RhB.js",
13
+ "_pages-CvUhOO9h.js": {
14
+ "file": "assets/pages-CvUhOO9h.js",
15
15
  "name": "pages",
16
16
  "imports": [
17
- "_vendor-Cfrr9FCF.js",
18
- "_vendor-arizeai-Dz0kN-lQ.js",
19
- "_components-CdQiQTvs.js",
20
- "_vendor-codemirror-ClqtONZQ.js",
21
- "_vendor-recharts-D6kvOpmb.js"
17
+ "_vendor-BdjZxMii.js",
18
+ "_vendor-arizeai-CHYlS8jV.js",
19
+ "_components-CFzdBkk_.js",
20
+ "_vendor-codemirror-Di6t4HnH.js",
21
+ "_vendor-recharts-C9wCDYj3.js"
22
22
  ]
23
23
  },
24
24
  "_vendor-BGzfc4EU.css": {
25
25
  "file": "assets/vendor-BGzfc4EU.css",
26
26
  "src": "_vendor-BGzfc4EU.css"
27
27
  },
28
- "_vendor-Cfrr9FCF.js": {
29
- "file": "assets/vendor-Cfrr9FCF.js",
28
+ "_vendor-BdjZxMii.js": {
29
+ "file": "assets/vendor-BdjZxMii.js",
30
30
  "name": "vendor",
31
31
  "imports": [
32
32
  "_vendor-three-BLWp5bic.js"
@@ -35,39 +35,39 @@
35
35
  "assets/vendor-BGzfc4EU.css"
36
36
  ]
37
37
  },
38
- "_vendor-arizeai-Dz0kN-lQ.js": {
39
- "file": "assets/vendor-arizeai-Dz0kN-lQ.js",
38
+ "_vendor-arizeai-CHYlS8jV.js": {
39
+ "file": "assets/vendor-arizeai-CHYlS8jV.js",
40
40
  "name": "vendor-arizeai",
41
41
  "imports": [
42
- "_vendor-Cfrr9FCF.js"
42
+ "_vendor-BdjZxMii.js"
43
43
  ]
44
44
  },
45
- "_vendor-codemirror-ClqtONZQ.js": {
46
- "file": "assets/vendor-codemirror-ClqtONZQ.js",
45
+ "_vendor-codemirror-Di6t4HnH.js": {
46
+ "file": "assets/vendor-codemirror-Di6t4HnH.js",
47
47
  "name": "vendor-codemirror",
48
48
  "imports": [
49
- "_vendor-Cfrr9FCF.js",
50
- "_vendor-shiki-xSOiKxt0.js"
49
+ "_vendor-BdjZxMii.js",
50
+ "_vendor-shiki-MNnmOotP.js"
51
51
  ],
52
52
  "dynamicImports": [
53
- "_vendor-shiki-xSOiKxt0.js",
54
- "_vendor-shiki-xSOiKxt0.js",
55
- "_vendor-shiki-xSOiKxt0.js"
53
+ "_vendor-shiki-MNnmOotP.js",
54
+ "_vendor-shiki-MNnmOotP.js",
55
+ "_vendor-shiki-MNnmOotP.js"
56
56
  ]
57
57
  },
58
- "_vendor-recharts-D6kvOpmb.js": {
59
- "file": "assets/vendor-recharts-D6kvOpmb.js",
58
+ "_vendor-recharts-C9wCDYj3.js": {
59
+ "file": "assets/vendor-recharts-C9wCDYj3.js",
60
60
  "name": "vendor-recharts",
61
61
  "imports": [
62
- "_vendor-Cfrr9FCF.js"
62
+ "_vendor-BdjZxMii.js"
63
63
  ]
64
64
  },
65
- "_vendor-shiki-xSOiKxt0.js": {
66
- "file": "assets/vendor-shiki-xSOiKxt0.js",
65
+ "_vendor-shiki-MNnmOotP.js": {
66
+ "file": "assets/vendor-shiki-MNnmOotP.js",
67
67
  "name": "vendor-shiki",
68
68
  "isDynamicEntry": true,
69
69
  "imports": [
70
- "_vendor-Cfrr9FCF.js"
70
+ "_vendor-BdjZxMii.js"
71
71
  ]
72
72
  },
73
73
  "_vendor-three-BLWp5bic.js": {
@@ -75,19 +75,19 @@
75
75
  "name": "vendor-three"
76
76
  },
77
77
  "index.tsx": {
78
- "file": "assets/index-B1VuXYRI.js",
78
+ "file": "assets/index-DayUA9lQ.js",
79
79
  "name": "index",
80
80
  "src": "index.tsx",
81
81
  "isEntry": true,
82
82
  "imports": [
83
- "_vendor-Cfrr9FCF.js",
84
- "_vendor-arizeai-Dz0kN-lQ.js",
85
- "_pages-CnfZ3RhB.js",
86
- "_components-CdQiQTvs.js",
83
+ "_vendor-BdjZxMii.js",
84
+ "_vendor-arizeai-CHYlS8jV.js",
85
+ "_pages-CvUhOO9h.js",
86
+ "_components-CFzdBkk_.js",
87
87
  "_vendor-three-BLWp5bic.js",
88
- "_vendor-codemirror-ClqtONZQ.js",
89
- "_vendor-shiki-xSOiKxt0.js",
90
- "_vendor-recharts-D6kvOpmb.js"
88
+ "_vendor-codemirror-Di6t4HnH.js",
89
+ "_vendor-shiki-MNnmOotP.js",
90
+ "_vendor-recharts-C9wCDYj3.js"
91
91
  ]
92
92
  }
93
93
  }