arize-phoenix 8.8.0__py3-none-any.whl → 8.10.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 (30) hide show
  1. {arize_phoenix-8.8.0.dist-info → arize_phoenix-8.10.0.dist-info}/METADATA +4 -4
  2. {arize_phoenix-8.8.0.dist-info → arize_phoenix-8.10.0.dist-info}/RECORD +30 -29
  3. phoenix/config.py +11 -0
  4. phoenix/experiments/types.py +2 -0
  5. phoenix/server/api/helpers/playground_clients.py +30 -2
  6. phoenix/server/api/helpers/prompts/models.py +23 -2
  7. phoenix/server/api/input_types/InvocationParameters.py +1 -0
  8. phoenix/server/api/mutations/__init__.py +3 -1
  9. phoenix/server/api/mutations/prompt_label_mutations.py +6 -5
  10. phoenix/server/api/mutations/prompt_mutations.py +6 -5
  11. phoenix/server/api/mutations/prompt_version_tag_mutations.py +3 -2
  12. phoenix/server/api/mutations/trace_mutations.py +74 -0
  13. phoenix/server/api/queries.py +14 -1
  14. phoenix/server/api/routers/v1/experiments.py +103 -2
  15. phoenix/server/api/routers/v1/prompts.py +14 -2
  16. phoenix/server/app.py +1 -1
  17. phoenix/server/static/.vite/manifest.json +44 -44
  18. phoenix/server/static/assets/{components-Cvwn-4Sk.js → components-CVzKofML.js} +245 -238
  19. phoenix/server/static/assets/{index-Cxmc6_pQ.js → index-Ctff7oin.js} +1 -1
  20. phoenix/server/static/assets/{pages-DLMdDkgQ.js → pages-CVFLHgre.js} +349 -340
  21. phoenix/server/static/assets/{vendor-yn6w6Ozi.js → vendor-VJCVsFqd.js} +161 -161
  22. phoenix/server/static/assets/{vendor-arizeai-DoGO67dU.js → vendor-arizeai-BiZagY4a.js} +22 -22
  23. phoenix/server/static/assets/{vendor-codemirror-BLdSYxpm.js → vendor-codemirror-0mUqu36F.js} +11 -11
  24. phoenix/server/static/assets/{vendor-recharts-CjOpOw1c.js → vendor-recharts-CfKQSOmq.js} +1 -1
  25. phoenix/server/static/assets/{vendor-shiki-BwTCxCQY.js → vendor-shiki-BsgMOuir.js} +1 -1
  26. phoenix/version.py +1 -1
  27. {arize_phoenix-8.8.0.dist-info → arize_phoenix-8.10.0.dist-info}/WHEEL +0 -0
  28. {arize_phoenix-8.8.0.dist-info → arize_phoenix-8.10.0.dist-info}/entry_points.txt +0 -0
  29. {arize_phoenix-8.8.0.dist-info → arize_phoenix-8.10.0.dist-info}/licenses/IP_NOTICE +0 -0
  30. {arize_phoenix-8.8.0.dist-info → arize_phoenix-8.10.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arize-phoenix
3
- Version: 8.8.0
3
+ Version: 8.10.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
@@ -48,7 +48,7 @@ Requires-Dist: scipy
48
48
  Requires-Dist: sqlalchemy[asyncio]<3,>=2.0.4
49
49
  Requires-Dist: sqlean-py>=3.45.1
50
50
  Requires-Dist: starlette
51
- Requires-Dist: strawberry-graphql==0.253.1
51
+ Requires-Dist: strawberry-graphql>=0.262.0
52
52
  Requires-Dist: tqdm
53
53
  Requires-Dist: typing-extensions>=4.6
54
54
  Requires-Dist: uvicorn
@@ -69,7 +69,7 @@ Requires-Dist: opentelemetry-sdk; extra == 'container'
69
69
  Requires-Dist: opentelemetry-semantic-conventions; extra == 'container'
70
70
  Requires-Dist: prometheus-client; extra == 'container'
71
71
  Requires-Dist: py-grpc-prometheus; extra == 'container'
72
- Requires-Dist: strawberry-graphql[opentelemetry]==0.253.1; extra == 'container'
72
+ Requires-Dist: strawberry-graphql[opentelemetry]==0.262.0; extra == 'container'
73
73
  Requires-Dist: umap-learn; extra == 'container'
74
74
  Requires-Dist: uvloop; (platform_system != 'Windows') and extra == 'container'
75
75
  Provides-Extra: dev
@@ -100,7 +100,7 @@ Requires-Dist: pytest-postgresql; extra == 'dev'
100
100
  Requires-Dist: pytest-xdist; extra == 'dev'
101
101
  Requires-Dist: pytest==8.3.3; extra == 'dev'
102
102
  Requires-Dist: ruff==0.6.9; extra == 'dev'
103
- Requires-Dist: strawberry-graphql[debug-server,opentelemetry]==0.253.1; extra == 'dev'
103
+ Requires-Dist: strawberry-graphql[debug-server,opentelemetry]==0.262.0; extra == 'dev'
104
104
  Requires-Dist: tabulate; extra == 'dev'
105
105
  Requires-Dist: tox-uv==1.11.3; extra == 'dev'
106
106
  Requires-Dist: tox==4.18.1; extra == 'dev'
@@ -1,12 +1,12 @@
1
1
  phoenix/__init__.py,sha256=X3eUEwd2rG8KKWWYVNNDJoqo08ihfjgHhlP29dcdNJE,5481
2
2
  phoenix/auth.py,sha256=VVMHrWN31tln3Zo4z6ofecrV4daiqJjLd8r85mqlxek,10939
3
- phoenix/config.py,sha256=V5DtJ5JZOqFr7CdXdYo_fPEDHVvxyY856xftHl3g9NY,29007
3
+ phoenix/config.py,sha256=dKSC-46EQrHVSYbUoQKoNOTTOGGWQC4tiiXe-UCLD2w,29483
4
4
  phoenix/datetime_utils.py,sha256=iJzNG6YJ6V7_u8B2iA7P2Z26FyxYbOPtx0dhJ7kNDHA,3398
5
5
  phoenix/exceptions.py,sha256=n2L2KKuecrdflB9MsCdAYCiSEvGJptIsfRkXMoJle7A,169
6
6
  phoenix/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
7
7
  phoenix/services.py,sha256=kpW1WL0kiB8XJsO6XycvZVJ-lBkNoenhQ7atCvBoSe8,5365
8
8
  phoenix/settings.py,sha256=ht-0oN-sMV6SPXrk7Tu1EZlngpAYkGNLYPhO8DyrdQI,661
9
- phoenix/version.py,sha256=lyCx9SueHF5AFRlBGLEidJOtooEa78uAc6Lvwe0BHU0,22
9
+ phoenix/version.py,sha256=wksB2Fuk1WwfEmtdei9zkvR3TbbzOltLZAcITFOP8sY,23
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
@@ -49,7 +49,7 @@ phoenix/db/types/model_provider.py,sha256=96UMeqiy5X9PmYMOWA6dZAmI_BSV3yVxt9HEVY
49
49
  phoenix/experiments/__init__.py,sha256=6JGwgUd7xCbGpuHqYZlsmErmYvVgv7N_j43bn3dUqsk,123
50
50
  phoenix/experiments/functions.py,sha256=QOwYNMO1qxG2bah4ZjJKMk7agFkZRWGvwyazLcwRCys,32573
51
51
  phoenix/experiments/tracing.py,sha256=seNh9rBH-rtQe8_FPI_VJj1rbo3ADcP6wDvERkMoxNc,2858
52
- phoenix/experiments/types.py,sha256=Vcks1zXuqrdu4Dy1TaNVcPHktgQY7WYin9yqaP2vrek,23390
52
+ phoenix/experiments/types.py,sha256=yntt6fnAny1U4Q9Y5Mm4ZYIb9319OaJovl-kyXFtGQE,23475
53
53
  phoenix/experiments/utils.py,sha256=MZ1-OnTcavk_KUtbfGqt55Fk9TGtJpYG_K71WsN-zDk,785
54
54
  phoenix/experiments/evaluators/__init__.py,sha256=CPWW1EiufLqc0JWghE4wVAPG_z6Wt4mD_-yf_4IckB4,772
55
55
  phoenix/experiments/evaluators/base.py,sha256=zefFLqyYLMxJnZxDs1S0QCrnb43YJraoadCMqRMU72A,5576
@@ -80,7 +80,7 @@ phoenix/pointcloud/pointcloud.py,sha256=SN_1wXZcwKrtSnHGZLDZGx71orqE1WyVF7E-D58d
80
80
  phoenix/pointcloud/projectors.py,sha256=TQgwc9cJDjJkin1WZyZzgl3HsYrLLiyWD7Czy4jNW3U,1088
81
81
  phoenix/pointcloud/umap_parameters.py,sha256=db_WEPoamuWtopZx7tQfAXPnoE0MS8FkAV0_ThjEx_Q,1735
82
82
  phoenix/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
- phoenix/server/app.py,sha256=3jSAFGkwr4Fqf0k3hKOkmhw1W1j9JI_7c2IOYZ2ewBk,39390
83
+ phoenix/server/app.py,sha256=nAjMImoLpP051uTldLPw98ggOJY-1zZiIjlPsG3DyXs,39379
84
84
  phoenix/server/bearer_auth.py,sha256=0UudvkAS_dxna5JEJJhGUYwB6Ny-e22ssX5Mm79QwCk,5907
85
85
  phoenix/server/dml_event.py,sha256=MjJmVEKytq75chBOSyvYDusUnEbg1pHpIjR3pZkUaJA,2838
86
86
  phoenix/server/dml_event_handler.py,sha256=EZLXmCvx4pJrCkz29gxwKwmvmUkTtPCHw6klR-XM8qE,8258
@@ -99,7 +99,7 @@ phoenix/server/api/auth.py,sha256=nywpmfMI1trZTbZRD3oBj4kFjzg_vnxDljcM431T1eY,12
99
99
  phoenix/server/api/context.py,sha256=OopBkMnY48TzulTtfuay3MXmhbFIWPtPoAsbhCW-Pl0,6459
100
100
  phoenix/server/api/exceptions.py,sha256=TA0JuY2YRnj35qGuMSQ8d0ToHum9gWm9W--3fSKHrX0,1171
101
101
  phoenix/server/api/interceptor.py,sha256=ykDnoC_apUd-llVli3m1CW18kNSIgjz2qZ6m5JmPDu8,1294
102
- phoenix/server/api/queries.py,sha256=QKZkLGzqDRa7EDfUADnk3jI0Rzsc_g_fe4y4oOBGbKw,34866
102
+ phoenix/server/api/queries.py,sha256=2D0vmNN853NA9-8OGri5ByEA4Di96uzzOLs4cmqL5Ls,35327
103
103
  phoenix/server/api/schema.py,sha256=fcs36xQwFF_Qe41_5cWR8wYpDvOrnbcyTeo5WNMbDsA,1702
104
104
  phoenix/server/api/subscriptions.py,sha256=DSIgQF6lQqkbc7D0AaI5R4g3hIHbU04H5Y2UIpwmpy0,22989
105
105
  phoenix/server/api/utils.py,sha256=quCBRcusc6PUq9tJq7M8PgwFZp7nXgVAxtbw8feribY,833
@@ -144,11 +144,11 @@ phoenix/server/api/dataloaders/cache/two_tier_cache.py,sha256=cmo8FUT3E91R139IEz
144
144
  phoenix/server/api/helpers/__init__.py,sha256=m2-xaSPqUiSs91k62JaRDjFNfl-1byxBfY-m_Vxw16U,272
145
145
  phoenix/server/api/helpers/dataset_helpers.py,sha256=DoMBTg-qXTnC_K4Evx1WKpCCYgRbITpVqyY-8efJRf0,8984
146
146
  phoenix/server/api/helpers/experiment_run_filters.py,sha256=DOnVwrmn39eAkk2mwuZP8kIcAnR5jrOgllEwWSjsw94,29893
147
- phoenix/server/api/helpers/playground_clients.py,sha256=tNl37HG2e14ehx1sVLhLHcRkZv2u9Dd8_521j1W1Qxw,40142
147
+ phoenix/server/api/helpers/playground_clients.py,sha256=lv8xoNNiNgfM58V5W1NrVzHgH2C8RRQWhjmNNud_nlg,41112
148
148
  phoenix/server/api/helpers/playground_registry.py,sha256=CPLMziFB2wmr-dfbx7VbzO2f8YIG_k5RftzvGXYGQ1w,2570
149
149
  phoenix/server/api/helpers/playground_spans.py,sha256=PjGNDc7cpqn5lmRM6TO_J1eVRGlgsNdQ8IT--5JVz0o,16881
150
150
  phoenix/server/api/helpers/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
151
- phoenix/server/api/helpers/prompts/models.py,sha256=10dIZlDy1a3sKmFk--Af5jk-8ATBqbNPXlOZYSIDwGk,18734
151
+ phoenix/server/api/helpers/prompts/models.py,sha256=zwWBA5GQvEHT4xyZwP-_kr1rJZ7SHnguATsQwsFw5aw,19519
152
152
  phoenix/server/api/helpers/prompts/conversions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
153
153
  phoenix/server/api/helpers/prompts/conversions/anthropic.py,sha256=uGTPzlw_9RaRPUsAIHyiRgD0NpDoajQzf7Am8nlJ4Cg,3279
154
154
  phoenix/server/api/helpers/prompts/conversions/openai.py,sha256=a43WAftFn_me6ePHDufqvlg-4Z2C31owUSsqYC0YUP8,2589
@@ -174,7 +174,7 @@ phoenix/server/api/input_types/DimensionFilter.py,sha256=eBYcn7ECSJQlEePvbStqkHB
174
174
  phoenix/server/api/input_types/DimensionInput.py,sha256=Vfx5FmiMKey4-EHDQsQRPzSAMRJMN5oVMLDUl4NKAa8,164
175
175
  phoenix/server/api/input_types/GenerativeModelInput.py,sha256=n6OCkX44I1AIovMAHCxy8SvqPKDb_BYDPA-fn_JnckQ,634
176
176
  phoenix/server/api/input_types/Granularity.py,sha256=dbBlD_GsIBa8_xrx4JlLuR59bQ0NRB5H-cv1zvcb-cw,2299
177
- phoenix/server/api/input_types/InvocationParameters.py,sha256=I_FvPvY2sXxNd-kFSB96-1DOW7lo-VbqVWzppU_5hy8,5196
177
+ phoenix/server/api/input_types/InvocationParameters.py,sha256=62xL0iIKvuQherkuJaJ6Lha4TTEoYLpvH-pEP9awK6k,5260
178
178
  phoenix/server/api/input_types/PatchAnnotationInput.py,sha256=NWhkcbcGNPwfOYsN3wm5YFNNrSc5T-8Y5my74RK99HE,520
179
179
  phoenix/server/api/input_types/PatchDatasetExamplesInput.py,sha256=_uMqkAInhLDvzUSASl6HgLNulTsekMcYzyd5J6LF90I,884
180
180
  phoenix/server/api/input_types/PatchDatasetInput.py,sha256=OURtTVY8Z_oFEDtKwT1LCMaOK5D4QYo5TVQ6mDrex-g,328
@@ -188,18 +188,19 @@ phoenix/server/api/input_types/TimeRange.py,sha256=pwhC2jx6dFIgT0qFfnO68qiJp9-m7
188
188
  phoenix/server/api/input_types/TraceAnnotationSort.py,sha256=BzwiUnMh2VsgQYnhDlbJ6ljHugqIS4YDUlYzvq_tl3o,365
189
189
  phoenix/server/api/input_types/UserRoleInput.py,sha256=xxhFe0ITZOgRVEJbVem_W6F1Ip_H6xDENdQqMMx-kKE,129
190
190
  phoenix/server/api/input_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
191
- phoenix/server/api/mutations/__init__.py,sha256=P28nrqaEjfwTI8ijBmVdWbCmtfQGhlG-_xYBqp7RvKc,1460
191
+ phoenix/server/api/mutations/__init__.py,sha256=MlJPciihC5gwE0AVkaqZhYeVkaCuuq1EaDTrs1MRw2I,1560
192
192
  phoenix/server/api/mutations/api_key_mutations.py,sha256=diNBL06zrFCmzR-leYbL-AxDqN05-YtbzsnsAdew_K8,6194
193
193
  phoenix/server/api/mutations/chat_mutations.py,sha256=ChRh4YbNkBgFO05CNElzqJ1hIvo7lr5Zn0lvlRs51pE,22997
194
194
  phoenix/server/api/mutations/dataset_mutations.py,sha256=V52mL0vizxL9cvWWBkmd19rGu8xvu-B8LOosZkROPIk,27004
195
195
  phoenix/server/api/mutations/experiment_mutations.py,sha256=p3CoLAa8nFPa3D759Y2A7De_PVJNGOL98mA3HoZBrRQ,3188
196
196
  phoenix/server/api/mutations/export_events_mutations.py,sha256=xoDnVWC7eA_8wNQP0-oyiHojyUZ0EhVVSrsAnztetC0,3993
197
197
  phoenix/server/api/mutations/project_mutations.py,sha256=u7kLvJbBFR418F9lMamiisZerF18E8h5wGKV4sDTF-g,2674
198
- phoenix/server/api/mutations/prompt_label_mutations.py,sha256=9k8Q_w8JbNbq8U9pKlu21sQ5450xfriWm19OYl7vi4g,6967
199
- phoenix/server/api/mutations/prompt_mutations.py,sha256=KwrcXbb361TxaFihei5Yt2a6Fg6LyObJz2VqICOOSYc,11754
200
- phoenix/server/api/mutations/prompt_version_tag_mutations.py,sha256=Jt4NBJn2EoAjiEI4ojNUXZs0TXZab-Erd-o2hvmapKw,5593
198
+ phoenix/server/api/mutations/prompt_label_mutations.py,sha256=uCiVcULtmgaNaav4M08ipPYM68sZv1MVLrCgvW-Xyn8,7317
199
+ phoenix/server/api/mutations/prompt_mutations.py,sha256=Yg-6L2PiKUZfFyNarptu3OdE0uA2_Nyl3VrLVP8FJ9Y,12114
200
+ phoenix/server/api/mutations/prompt_version_tag_mutations.py,sha256=t77osYb5he2Am4UeNis7pzY9MnaA9PNEQhsQelRH8k8,5767
201
201
  phoenix/server/api/mutations/span_annotations_mutations.py,sha256=sumBLUqRKlgMASWdWwYItmIJ2l7AyAp_PlIYeXYfguc,5970
202
202
  phoenix/server/api/mutations/trace_annotations_mutations.py,sha256=sEcEt8hbMt8YMiRX5o3xcJ5rWWZbDeBPMNz2teZoi3U,5945
203
+ phoenix/server/api/mutations/trace_mutations.py,sha256=D5h2HYdlTo6yYZNq-O-PjaS9GeiZHxxVaOxDdh7fwjw,2957
203
204
  phoenix/server/api/mutations/user_mutations.py,sha256=FgZXQjCqmJ_0dyqiXv6NoGF7TjOO2a0aX7xDMDKtl-A,13603
204
205
  phoenix/server/api/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
205
206
  phoenix/server/api/openapi/main.py,sha256=yKdzJYI4cxy_1mFcK4_7YObIcuRviBIfwNjB23RG14k,461
@@ -214,9 +215,9 @@ phoenix/server/api/routers/v1/datasets.py,sha256=gHlF4x0EmWiJ-8vwJygoh0bO3gvDBmi
214
215
  phoenix/server/api/routers/v1/evaluations.py,sha256=RpOkTylp5Da6BvPZGuN8ksnxz_BVXRIwyOvwX9Iko8U,12647
215
216
  phoenix/server/api/routers/v1/experiment_evaluations.py,sha256=vx4CKlE84sAL1vtPiM_XWnbfrATQujOSzzduJDYgcyM,4829
216
217
  phoenix/server/api/routers/v1/experiment_runs.py,sha256=bInuasRv7ogiYf8fq-LwpJ5tptmMQsBNDlJAqwdymko,6378
217
- phoenix/server/api/routers/v1/experiments.py,sha256=cwpRWTjreXPqBoeYPv6pNrb3445MT1E6eDRuvj-3Paw,11799
218
+ phoenix/server/api/routers/v1/experiments.py,sha256=yJh48HSFjBB5PtQld9Kt2CxAYdpekl0jjIyeVHB30oE,15826
218
219
  phoenix/server/api/routers/v1/models.py,sha256=r0nM2kFJ3mxDqgc5vFr1cjNuyOPs3RIKE_DS2VMdF48,1749
219
- phoenix/server/api/routers/v1/prompts.py,sha256=kRsssgRulr-ys0ouLz4qG-TP-uG30UZcfTqc6hGwo08,14485
220
+ phoenix/server/api/routers/v1/prompts.py,sha256=ytK8HnOZNxUMDtC7XAFxzaTSM9DMMua13vWsqqd4PAw,14986
220
221
  phoenix/server/api/routers/v1/spans.py,sha256=uoU_bwIgz86fuvPjP5sX8goDyuCcnsTig-x3f17p60U,9625
221
222
  phoenix/server/api/routers/v1/traces.py,sha256=hSv35QIB4mwFgp53rOpz3zWIiSwbZzQnjafD790QuJU,7908
222
223
  phoenix/server/api/routers/v1/utils.py,sha256=SoRl0Dc8By15ZckhNcXg2QRrqYjMvgTjVcqrZ6MwVmo,3065
@@ -313,17 +314,17 @@ phoenix/server/static/apple-touch-icon-76x76.png,sha256=CT_xT12I0u2i0WU8JzBZBuOQ
313
314
  phoenix/server/static/apple-touch-icon.png,sha256=fOfpjqGpWYbJ0eAurKsyoZP1EAs6ZVooBJ_SGk2ZkDs,3801
314
315
  phoenix/server/static/favicon.ico,sha256=bY0vvCKRftemZfPShwZtE93DiiQdaYaozkPGwNFr6H8,34494
315
316
  phoenix/server/static/modernizr.js,sha256=mvK-XtkNqjOral-QvzoqsyOMECXIMu5BQwSVN_wcU9c,2564
316
- phoenix/server/static/.vite/manifest.json,sha256=6ryOprN2R2b58dJngby9Yv3SDjputIfmbF8NdQHOUNE,2165
317
- phoenix/server/static/assets/components-Cvwn-4Sk.js,sha256=3WRHjTfCjcXZKjLVkNsY9kHIHQfUOJ7wKjqLGg-A6Oc,423203
318
- phoenix/server/static/assets/index-Cxmc6_pQ.js,sha256=P9cuaCT30kzwb6PQfeBunYMitAvMruHf1RPkp4hmHkQ,59207
319
- phoenix/server/static/assets/pages-DLMdDkgQ.js,sha256=a5VH-3_PFRQPEGjZ4WeeFDNiCvEE2JYNtxeTReNjzvI,836948
317
+ phoenix/server/static/.vite/manifest.json,sha256=RVqrVl8ER15uOPhyqrvlOhvtDW4I4yqwKgetXJ7Ds9o,2165
318
+ phoenix/server/static/assets/components-CVzKofML.js,sha256=ncp4gOOq5QdYz_LBPdLy4zTPGIEEmmnQSfVjb8kd3KI,424183
319
+ phoenix/server/static/assets/index-Ctff7oin.js,sha256=msNwFX-LMi191AKNaA_wAUctTK-RewbdMkSsjn2FH-E,59207
320
+ phoenix/server/static/assets/pages-CVFLHgre.js,sha256=sJDoDq-r9tNwyH6b4SKJYyeymn29wCQ14hAl5ZPYJ90,840022
320
321
  phoenix/server/static/assets/vendor-Cg6lcjUC.css,sha256=nZrkr0u6NNElFGvpWHk9GTHeGoibCXCli1bE7mXZGZg,1816
321
- phoenix/server/static/assets/vendor-arizeai-DoGO67dU.js,sha256=Rw1UPVWqJ4kV_n5mdr5t89ADWRBxbdHVObTbx--81S8,202331
322
- phoenix/server/static/assets/vendor-codemirror-BLdSYxpm.js,sha256=VObEa3PGY2JNemLuOXNczCALhI5I9k8yI6a6G8C-Kwc,393505
323
- phoenix/server/static/assets/vendor-recharts-CjOpOw1c.js,sha256=aA2Y0gIqOCq8VYDwRT66P7LypCHnY_Zysz79YBxe_0o,282095
324
- phoenix/server/static/assets/vendor-shiki-BwTCxCQY.js,sha256=2okHp2yxVOikaMS2HlgctZmrC2YfSfzAyfCuO6nFP0k,8980312
322
+ phoenix/server/static/assets/vendor-VJCVsFqd.js,sha256=d5PqgO3T3CRxy2q7Jk4b-1MVab_E3kKeDg3OtBILa0E,2265494
323
+ phoenix/server/static/assets/vendor-arizeai-BiZagY4a.js,sha256=v9L6kaDEhwTmE76ilfx5BJ89lGXjmyWft580Ei3vQ4Q,202788
324
+ phoenix/server/static/assets/vendor-codemirror-0mUqu36F.js,sha256=WOPvKseqLr9P1W5beQJSTX3m_6JIkbx7xjWWZK8qHeE,393496
325
+ phoenix/server/static/assets/vendor-recharts-CfKQSOmq.js,sha256=TWJ68mOSnbpn8XscPz1N3Zs-EkLLqYDtgQ25vDJCL4I,282095
326
+ phoenix/server/static/assets/vendor-shiki-BsgMOuir.js,sha256=cFiYo70OgEzfurmjGOmzkxAWdlOcSEfZBSY6RFqA0mk,8980312
325
327
  phoenix/server/static/assets/vendor-three-C-AGeJYv.js,sha256=c9nLPH5YDRFCzTNuwWO8_5KqcnunPo53mQsb7y9JFW8,620972
326
- phoenix/server/static/assets/vendor-yn6w6Ozi.js,sha256=z2z4fixLGqjG1VhhAy0Mm2sjYlkgmi97-hbwWsIFCE8,2259231
327
328
  phoenix/server/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
328
329
  phoenix/server/templates/index.html,sha256=e8_jdi7Eo19SK7DI_gglkTW094D17E0VAegoMmmmvIc,4330
329
330
  phoenix/session/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -363,9 +364,9 @@ phoenix/utilities/project.py,sha256=auVpARXkDb-JgeX5f2aStyFIkeKvGwN9l7qrFeJMVxI,
363
364
  phoenix/utilities/re.py,sha256=6YyUWIkv0zc2SigsxfOWIHzdpjKA_TZo2iqKq7zJKvw,2081
364
365
  phoenix/utilities/span_store.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
365
366
  phoenix/utilities/template_formatters.py,sha256=gh9PJD6WEGw7TEYXfSst1UR4pWWwmjxMLrDVQ_CkpkQ,2779
366
- arize_phoenix-8.8.0.dist-info/METADATA,sha256=lGcigkNJ8vJm16nScXXkp3Auz758fMdE8FxPMCggCU8,23738
367
- arize_phoenix-8.8.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
368
- arize_phoenix-8.8.0.dist-info/entry_points.txt,sha256=Pgpn8Upxx9P8z8joPXZWl2LlnAlGc3gcQoVchb06X1Q,94
369
- arize_phoenix-8.8.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
370
- arize_phoenix-8.8.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
371
- arize_phoenix-8.8.0.dist-info/RECORD,,
367
+ arize_phoenix-8.10.0.dist-info/METADATA,sha256=WmPj1Vucp2RIf0uaIQHillrSRggnUxrtUJ_xdu8COGs,23739
368
+ arize_phoenix-8.10.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
369
+ arize_phoenix-8.10.0.dist-info/entry_points.txt,sha256=Pgpn8Upxx9P8z8joPXZWl2LlnAlGc3gcQoVchb06X1Q,94
370
+ arize_phoenix-8.10.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
371
+ arize_phoenix-8.10.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
372
+ arize_phoenix-8.10.0.dist-info/RECORD,,
phoenix/config.py CHANGED
@@ -86,6 +86,13 @@ ENV_PHOENIX_SQL_DATABASE_SCHEMA = "PHOENIX_SQL_DATABASE_SCHEMA"
86
86
  The schema to use for the PostgresSQL database. (This is ignored for SQLite.)
87
87
  See e.g. https://www.postgresql.org/docs/current/ddl-schemas.html
88
88
  """
89
+ ENV_PHOENIX_DATABASE_ALLOCATED_STORAGE_CAPACITY_GIBIBYTES = (
90
+ "PHOENIX_DATABASE_ALLOCATED_STORAGE_CAPACITY_GIBIBYTES"
91
+ )
92
+ """
93
+ The allocated storage capacity for the Phoenix database in gibibytes (2^30 bytes). Use float for
94
+ fractional value. This is currently used only by the UI for informational displays.
95
+ """
89
96
  ENV_PHOENIX_ENABLE_PROMETHEUS = "PHOENIX_ENABLE_PROMETHEUS"
90
97
  """
91
98
  Whether to enable Prometheus. Defaults to false.
@@ -690,6 +697,10 @@ def get_env_database_schema() -> Optional[str]:
690
697
  return getenv(ENV_PHOENIX_SQL_DATABASE_SCHEMA)
691
698
 
692
699
 
700
+ def get_env_database_allocated_storage_capacity_gibibytes() -> Optional[float]:
701
+ return _float_val(ENV_PHOENIX_DATABASE_ALLOCATED_STORAGE_CAPACITY_GIBIBYTES)
702
+
703
+
693
704
  def get_env_enable_prometheus() -> bool:
694
705
  if (enable_promotheus := getenv(ENV_PHOENIX_ENABLE_PROMETHEUS)) is None or (
695
706
  enable_promotheus_lower := enable_promotheus.lower()
@@ -282,6 +282,8 @@ class ExperimentEvaluationRun:
282
282
  ExperimentTask: TypeAlias = Union[
283
283
  Callable[[Example], TaskOutput],
284
284
  Callable[[Example], Awaitable[TaskOutput]],
285
+ Callable[..., JSONSerializable],
286
+ Callable[..., Awaitable[JSONSerializable]],
285
287
  ]
286
288
 
287
289
 
@@ -761,6 +761,13 @@ class AnthropicStreamingClient(PlaygroundStreamingClient):
761
761
  import anthropic.types as anthropic_types
762
762
 
763
763
  anthropic_messages, system_prompt = self._build_anthropic_messages(messages)
764
+ if (
765
+ "thinking" in invocation_parameters
766
+ and isinstance(invocation_parameters, dict)
767
+ and "type" in invocation_parameters["thinking"]
768
+ and invocation_parameters["thinking"]["type"] == "enabled"
769
+ ):
770
+ invocation_parameters.pop("top_p", None)
764
771
  anthropic_params = {
765
772
  "messages": anthropic_messages,
766
773
  "model": self.model_name,
@@ -810,9 +817,9 @@ class AnthropicStreamingClient(PlaygroundStreamingClient):
810
817
  elif isinstance(event, anthropic_streaming._types.CitationEvent):
811
818
  raise NotImplementedError
812
819
  elif isinstance(event, anthropic_streaming._types.ThinkingEvent):
813
- raise NotImplementedError
820
+ pass
814
821
  elif isinstance(event, anthropic_streaming._types.SignatureEvent):
815
- raise NotImplementedError
822
+ pass
816
823
  else:
817
824
  assert_never(event)
818
825
 
@@ -862,6 +869,27 @@ class AnthropicStreamingClient(PlaygroundStreamingClient):
862
869
  return content
863
870
 
864
871
 
872
+ @register_llm_client(
873
+ provider_key=GenerativeProviderKey.ANTHROPIC,
874
+ model_names=[
875
+ "claude-3-7-sonnet-latest",
876
+ "claude-3-7-sonnet-20250219",
877
+ ],
878
+ )
879
+ class AnthropicReasoningStreamingClient(AnthropicStreamingClient):
880
+ @classmethod
881
+ def supported_invocation_parameters(cls) -> list[InvocationParameter]:
882
+ invocation_params = super().supported_invocation_parameters()
883
+ invocation_params.append(
884
+ JSONInvocationParameter(
885
+ invocation_name="thinking",
886
+ canonical_name=CanonicalParameterName.ANTHROPIC_EXTENDED_THINKING,
887
+ label="Thinking Budget",
888
+ )
889
+ )
890
+ return invocation_params
891
+
892
+
865
893
  @register_llm_client(
866
894
  provider_key=GenerativeProviderKey.GOOGLE,
867
895
  model_names=[
@@ -3,8 +3,8 @@ from __future__ import annotations
3
3
  from enum import Enum
4
4
  from typing import Any, Literal, Mapping, Optional, Union
5
5
 
6
- from pydantic import BaseModel, ConfigDict, Field, RootModel
7
- from typing_extensions import Annotated, TypeAlias, TypeGuard, assert_never
6
+ from pydantic import BaseModel, ConfigDict, Field, RootModel, model_validator
7
+ from typing_extensions import Annotated, Self, TypeAlias, TypeGuard, assert_never
8
8
 
9
9
  from phoenix.db.types.model_provider import ModelProvider
10
10
  from phoenix.server.api.helpers.prompts.conversions.anthropic import AnthropicToolChoiceConversion
@@ -370,11 +370,32 @@ class PromptAzureOpenAIInvocationParameters(PromptModel):
370
370
  azure_openai: PromptAzureOpenAIInvocationParametersContent
371
371
 
372
372
 
373
+ class PromptAnthropicThinkingConfigDisabled(PromptModel):
374
+ type: Literal["disabled"]
375
+
376
+
377
+ class PromptAnthropicThinkingConfigEnabled(PromptModel):
378
+ type: Literal["enabled"]
379
+ budget_tokens: int = Field(..., ge=1024)
380
+
381
+
373
382
  class PromptAnthropicInvocationParametersContent(PromptModel):
374
383
  max_tokens: int
375
384
  temperature: float = UNDEFINED
376
385
  top_p: float = UNDEFINED
377
386
  stop_sequences: list[str] = UNDEFINED
387
+ thinking: Annotated[
388
+ Union[PromptAnthropicThinkingConfigDisabled, PromptAnthropicThinkingConfigEnabled],
389
+ Field(..., discriminator="type"),
390
+ ] = UNDEFINED
391
+
392
+ @model_validator(mode="after")
393
+ def check_thinking_budget_tokens_lt_max_tokens(self) -> Self:
394
+ if self.thinking is UNDEFINED:
395
+ return self
396
+ if self.thinking.type == "enabled" and self.thinking.budget_tokens >= self.max_tokens:
397
+ raise ValueError("The thinking budget must be less than max tokens.")
398
+ return self
378
399
 
379
400
 
380
401
  class PromptAnthropicInvocationParameters(PromptModel):
@@ -16,6 +16,7 @@ class CanonicalParameterName(str, Enum):
16
16
  TOOL_CHOICE = "tool_choice"
17
17
  RESPONSE_FORMAT = "response_format"
18
18
  REASONING_EFFORT = "reasoning_effort"
19
+ ANTHROPIC_EXTENDED_THINKING = "anthropic_extended_thinking"
19
20
 
20
21
 
21
22
  @strawberry.enum
@@ -13,12 +13,14 @@ from phoenix.server.api.mutations.prompt_mutations import PromptMutationMixin
13
13
  from phoenix.server.api.mutations.prompt_version_tag_mutations import PromptVersionTagMutationMixin
14
14
  from phoenix.server.api.mutations.span_annotations_mutations import SpanAnnotationMutationMixin
15
15
  from phoenix.server.api.mutations.trace_annotations_mutations import TraceAnnotationMutationMixin
16
+ from phoenix.server.api.mutations.trace_mutations import TraceMutationMixin
16
17
  from phoenix.server.api.mutations.user_mutations import UserMutationMixin
17
18
 
18
19
 
19
20
  @strawberry.type
20
21
  class Mutation(
21
22
  ApiKeyMutationMixin,
23
+ ChatCompletionMutationMixin,
22
24
  DatasetMutationMixin,
23
25
  ExperimentMutationMixin,
24
26
  ExportEventsMutationMixin,
@@ -28,7 +30,7 @@ class Mutation(
28
30
  PromptLabelMutationMixin,
29
31
  SpanAnnotationMutationMixin,
30
32
  TraceAnnotationMutationMixin,
33
+ TraceMutationMixin,
31
34
  UserMutationMixin,
32
- ChatCompletionMutationMixin,
33
35
  ):
34
36
  pass
@@ -11,6 +11,7 @@ from strawberry.types import Info
11
11
 
12
12
  from phoenix.db import models
13
13
  from phoenix.db.types.identifier import Identifier as IdentifierModel
14
+ from phoenix.server.api.auth import IsLocked, IsNotReadOnly
14
15
  from phoenix.server.api.context import Context
15
16
  from phoenix.server.api.exceptions import Conflict, NotFound
16
17
  from phoenix.server.api.queries import Query
@@ -58,7 +59,7 @@ class PromptLabelMutationPayload:
58
59
 
59
60
  @strawberry.type
60
61
  class PromptLabelMutationMixin:
61
- @strawberry.mutation
62
+ @strawberry.mutation(permission_classes=[IsNotReadOnly, IsLocked]) # type: ignore
62
63
  async def create_prompt_label(
63
64
  self, info: Info[Context, None], input: CreatePromptLabelInput
64
65
  ) -> PromptLabelMutationPayload:
@@ -77,7 +78,7 @@ class PromptLabelMutationMixin:
77
78
  query=Query(),
78
79
  )
79
80
 
80
- @strawberry.mutation
81
+ @strawberry.mutation(permission_classes=[IsNotReadOnly, IsLocked]) # type: ignore
81
82
  async def patch_prompt_label(
82
83
  self, info: Info[Context, None], input: PatchPromptLabelInput
83
84
  ) -> PromptLabelMutationPayload:
@@ -106,7 +107,7 @@ class PromptLabelMutationMixin:
106
107
  query=Query(),
107
108
  )
108
109
 
109
- @strawberry.mutation
110
+ @strawberry.mutation(permission_classes=[IsNotReadOnly]) # type: ignore
110
111
  async def delete_prompt_label(
111
112
  self, info: Info[Context, None], input: DeletePromptLabelInput
112
113
  ) -> PromptLabelMutationPayload:
@@ -130,7 +131,7 @@ class PromptLabelMutationMixin:
130
131
  query=Query(),
131
132
  )
132
133
 
133
- @strawberry.mutation
134
+ @strawberry.mutation(permission_classes=[IsNotReadOnly, IsLocked]) # type: ignore
134
135
  async def set_prompt_label(
135
136
  self, info: Info[Context, None], input: SetPromptLabelInput
136
137
  ) -> PromptLabelMutationPayload:
@@ -160,7 +161,7 @@ class PromptLabelMutationMixin:
160
161
  query=Query(),
161
162
  )
162
163
 
163
- @strawberry.mutation
164
+ @strawberry.mutation(permission_classes=[IsNotReadOnly]) # type: ignore
164
165
  async def unset_prompt_label(
165
166
  self, info: Info[Context, None], input: UnsetPromptLabelInput
166
167
  ) -> PromptLabelMutationPayload:
@@ -13,6 +13,7 @@ from strawberry.types import Info
13
13
  from phoenix.db import models
14
14
  from phoenix.db.types.identifier import Identifier as IdentifierModel
15
15
  from phoenix.db.types.model_provider import ModelProvider
16
+ from phoenix.server.api.auth import IsLocked, IsNotReadOnly
16
17
  from phoenix.server.api.context import Context
17
18
  from phoenix.server.api.exceptions import BadRequest, Conflict, NotFound
18
19
  from phoenix.server.api.helpers.prompts.models import (
@@ -74,7 +75,7 @@ class DeletePromptMutationPayload:
74
75
 
75
76
  @strawberry.type
76
77
  class PromptMutationMixin:
77
- @strawberry.mutation
78
+ @strawberry.mutation(permission_classes=[IsNotReadOnly, IsLocked]) # type: ignore
78
79
  async def create_chat_prompt(
79
80
  self, info: Info[Context, None], input: CreateChatPromptInput
80
81
  ) -> Prompt:
@@ -141,7 +142,7 @@ class PromptMutationMixin:
141
142
  raise Conflict(f"A prompt named '{input.name}' already exists")
142
143
  return to_gql_prompt_from_orm(prompt)
143
144
 
144
- @strawberry.mutation
145
+ @strawberry.mutation(permission_classes=[IsNotReadOnly, IsLocked]) # type: ignore
145
146
  async def create_chat_prompt_version(
146
147
  self,
147
148
  info: Info[Context, None],
@@ -219,7 +220,7 @@ class PromptMutationMixin:
219
220
 
220
221
  return to_gql_prompt_from_orm(prompt)
221
222
 
222
- @strawberry.mutation
223
+ @strawberry.mutation(permission_classes=[IsNotReadOnly]) # type: ignore
223
224
  async def delete_prompt(
224
225
  self, info: Info[Context, None], input: DeletePromptInput
225
226
  ) -> DeletePromptMutationPayload:
@@ -236,7 +237,7 @@ class PromptMutationMixin:
236
237
  await session.commit()
237
238
  return DeletePromptMutationPayload(query=Query())
238
239
 
239
- @strawberry.mutation
240
+ @strawberry.mutation(permission_classes=[IsNotReadOnly, IsLocked]) # type: ignore
240
241
  async def clone_prompt(self, info: Info[Context, None], input: ClonePromptInput) -> Prompt:
241
242
  prompt_id = from_global_id_with_expected_type(
242
243
  global_id=input.prompt_id, expected_type_name=Prompt.__name__
@@ -289,7 +290,7 @@ class PromptMutationMixin:
289
290
  raise Conflict(f"A prompt named '{input.name}' already exists")
290
291
  return to_gql_prompt_from_orm(new_prompt)
291
292
 
292
- @strawberry.mutation
293
+ @strawberry.mutation(permission_classes=[IsNotReadOnly, IsLocked]) # type: ignore
293
294
  async def patch_prompt(self, info: Info[Context, None], input: PatchPromptInput) -> Prompt:
294
295
  prompt_id = from_global_id_with_expected_type(
295
296
  global_id=input.prompt_id, expected_type_name=Prompt.__name__
@@ -10,6 +10,7 @@ from strawberry.types import Info
10
10
 
11
11
  from phoenix.db import models
12
12
  from phoenix.db.types.identifier import Identifier as IdentifierModel
13
+ from phoenix.server.api.auth import IsLocked, IsNotReadOnly
13
14
  from phoenix.server.api.context import Context
14
15
  from phoenix.server.api.exceptions import BadRequest, Conflict, NotFound
15
16
  from phoenix.server.api.queries import Query
@@ -41,7 +42,7 @@ class PromptVersionTagMutationPayload:
41
42
 
42
43
  @strawberry.type
43
44
  class PromptVersionTagMutationMixin:
44
- @strawberry.mutation
45
+ @strawberry.mutation(permission_classes=[IsNotReadOnly]) # type: ignore
45
46
  async def delete_prompt_version_tag(
46
47
  self, info: Info[Context, None], input: DeletePromptVersionTagInput
47
48
  ) -> PromptVersionTagMutationPayload:
@@ -77,7 +78,7 @@ class PromptVersionTagMutationMixin:
77
78
  prompt_version_tag=None, query=Query(), prompt=to_gql_prompt_from_orm(prompt)
78
79
  )
79
80
 
80
- @strawberry.mutation
81
+ @strawberry.mutation(permission_classes=[IsNotReadOnly, IsLocked]) # type: ignore
81
82
  async def set_prompt_version_tag(
82
83
  self, info: Info[Context, None], input: SetPromptVersionTagInput
83
84
  ) -> PromptVersionTagMutationPayload:
@@ -0,0 +1,74 @@
1
+ import strawberry
2
+ from sqlalchemy import and_, delete, not_, select
3
+ from sqlalchemy.orm import load_only
4
+ from sqlalchemy.sql import literal
5
+ from strawberry.relay import GlobalID
6
+ from strawberry.types import Info
7
+
8
+ from phoenix.db import models
9
+ from phoenix.server.api.auth import IsNotReadOnly
10
+ from phoenix.server.api.context import Context
11
+ from phoenix.server.api.exceptions import BadRequest
12
+ from phoenix.server.api.queries import Query
13
+ from phoenix.server.api.types.node import from_global_id_with_expected_type
14
+ from phoenix.server.dml_event import SpanDeleteEvent
15
+
16
+
17
+ @strawberry.type
18
+ class TraceMutationMixin:
19
+ @strawberry.mutation(permission_classes=[IsNotReadOnly]) # type: ignore
20
+ async def delete_traces(
21
+ self,
22
+ info: Info[Context, None],
23
+ trace_ids: list[GlobalID],
24
+ ) -> Query:
25
+ if not trace_ids:
26
+ raise BadRequest("Must provide at least one trace ID to delete")
27
+ trace_ids = list(set(trace_ids))
28
+ try:
29
+ trace_rowids = [
30
+ from_global_id_with_expected_type(global_id=id, expected_type_name="Trace")
31
+ for id in trace_ids
32
+ ]
33
+ except ValueError as error:
34
+ raise BadRequest(str(error))
35
+ async with info.context.db() as session:
36
+ traces = (
37
+ await session.scalars(
38
+ delete(models.Trace)
39
+ .where(models.Trace.id.in_(trace_rowids))
40
+ .returning(models.Trace)
41
+ .options(
42
+ load_only(models.Trace.project_rowid, models.Trace.project_session_rowid)
43
+ )
44
+ )
45
+ ).all()
46
+ if len(traces) < len(trace_rowids):
47
+ await session.rollback()
48
+ raise BadRequest("Invalid trace IDs provided")
49
+ project_ids = tuple(set(trace.project_rowid for trace in traces))
50
+ if len(project_ids) > 1:
51
+ await session.rollback()
52
+ raise BadRequest("Cannot delete traces from multiple projects")
53
+ session_ids = set(
54
+ session_id
55
+ for trace in traces
56
+ if (session_id := trace.project_session_rowid) is not None
57
+ )
58
+ if session_ids:
59
+ await session.execute(
60
+ delete(models.ProjectSession).where(
61
+ and_(
62
+ models.ProjectSession.id.in_(session_ids),
63
+ not_(
64
+ select(literal(1))
65
+ .where(
66
+ models.Trace.project_session_rowid == models.ProjectSession.id
67
+ )
68
+ .exists()
69
+ ),
70
+ )
71
+ )
72
+ )
73
+ info.context.event_queue.put(SpanDeleteEvent(project_ids))
74
+ return Query()
@@ -13,7 +13,11 @@ from strawberry.relay import Connection, GlobalID, Node
13
13
  from strawberry.types import Info
14
14
  from typing_extensions import Annotated, TypeAlias, assert_never
15
15
 
16
- from phoenix.config import ENV_PHOENIX_SQL_DATABASE_SCHEMA, getenv
16
+ from phoenix.config import (
17
+ ENV_PHOENIX_SQL_DATABASE_SCHEMA,
18
+ get_env_database_allocated_storage_capacity_gibibytes,
19
+ getenv,
20
+ )
17
21
  from phoenix.db import enums, models
18
22
  from phoenix.db.helpers import SupportedSQLDialect
19
23
  from phoenix.db.models import DatasetExample as OrmExample
@@ -789,6 +793,15 @@ class Query:
789
793
  clustered_events=clustered_events,
790
794
  )
791
795
 
796
+ @strawberry.field(
797
+ description="The allocated storage capacity of the database in bytes. "
798
+ "Return None if this information is unavailable.",
799
+ ) # type: ignore
800
+ async def db_storage_capacity_bytes(self) -> Optional[float]:
801
+ if gibibytes := get_env_database_allocated_storage_capacity_gibibytes():
802
+ return gibibytes * 2**30
803
+ return None
804
+
792
805
  @strawberry.field
793
806
  async def db_table_stats(
794
807
  self,