arize-phoenix 11.30.0__py3-none-any.whl → 11.32.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.
- {arize_phoenix-11.30.0.dist-info → arize_phoenix-11.32.0.dist-info}/METADATA +17 -17
- {arize_phoenix-11.30.0.dist-info → arize_phoenix-11.32.0.dist-info}/RECORD +26 -25
- phoenix/db/types/trace_retention.py +1 -1
- phoenix/experiments/functions.py +69 -19
- phoenix/server/api/dataloaders/document_evaluations.py +6 -9
- phoenix/server/api/routers/v1/annotations.py +128 -5
- phoenix/server/api/routers/v1/documents.py +47 -79
- phoenix/server/api/routers/v1/experiment_runs.py +71 -31
- phoenix/server/api/routers/v1/spans.py +2 -48
- phoenix/server/api/routers/v1/traces.py +19 -55
- phoenix/server/api/types/Dataset.py +8 -66
- phoenix/server/api/types/DatasetExperimentAnnotationSummary.py +10 -0
- phoenix/server/api/types/DocumentAnnotation.py +92 -0
- phoenix/server/api/types/Span.py +8 -2
- phoenix/server/api/types/TraceAnnotation.py +8 -5
- phoenix/server/cost_tracking/model_cost_manifest.json +91 -0
- phoenix/server/static/.vite/manifest.json +9 -9
- phoenix/server/static/assets/{components-BBwXqJXQ.js → components-Cs9c4Nxp.js} +1 -1
- phoenix/server/static/assets/{index-C_gU3x10.js → index-D1FDMBMV.js} +1 -1
- phoenix/server/static/assets/{pages-YmQb55Uo.js → pages-Cbj9SjBx.js} +488 -463
- phoenix/trace/projects.py +6 -0
- phoenix/version.py +1 -1
- phoenix/server/api/types/Evaluation.py +0 -40
- {arize_phoenix-11.30.0.dist-info → arize_phoenix-11.32.0.dist-info}/WHEEL +0 -0
- {arize_phoenix-11.30.0.dist-info → arize_phoenix-11.32.0.dist-info}/entry_points.txt +0 -0
- {arize_phoenix-11.30.0.dist-info → arize_phoenix-11.32.0.dist-info}/licenses/IP_NOTICE +0 -0
- {arize_phoenix-11.30.0.dist-info → arize_phoenix-11.32.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.
|
|
3
|
+
Version: 11.32.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
|
|
@@ -201,14 +201,14 @@ The `arize-phoenix` package includes the entire Phoenix platfom. However if you
|
|
|
201
201
|
|
|
202
202
|
### Subpackages
|
|
203
203
|
|
|
204
|
-
| Package |
|
|
205
|
-
| --------------------------------------------------------------------------------------------------- |
|
|
206
|
-
| [arize-phoenix-otel](https://github.com/Arize-ai/phoenix/tree/main/packages/phoenix-otel) |
|
|
207
|
-
| [arize-phoenix-client](https://github.com/Arize-ai/phoenix/tree/main/packages/phoenix-client) |
|
|
208
|
-
| [arize-phoenix-evals](https://github.com/Arize-ai/phoenix/tree/main/packages/phoenix-evals) |
|
|
209
|
-
| [@arizeai/phoenix-client](https://github.com/Arize-ai/phoenix/tree/main/js/packages/phoenix-client) |
|
|
210
|
-
| [@arizeai/phoenix-evals](https://github.com/Arize-ai/phoenix/tree/main/js/packages/phoenix-evals) |
|
|
211
|
-
| [@arizeai/phoenix-mcp](https://github.com/Arize-ai/phoenix/tree/main/js/packages/phoenix-mcp) |
|
|
204
|
+
| Package | Version & Docs | Description |
|
|
205
|
+
| --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
206
|
+
| [arize-phoenix-otel](https://github.com/Arize-ai/phoenix/tree/main/packages/phoenix-otel) | [](https://pypi.org/project/arize-phoenix-otel/) [](https://arize-phoenix.readthedocs.io/projects/otel/en/latest/index.html) | Provides a lightweight wrapper around OpenTelemetry primitives with Phoenix-aware defaults |
|
|
207
|
+
| [arize-phoenix-client](https://github.com/Arize-ai/phoenix/tree/main/packages/phoenix-client) | [](https://pypi.org/project/arize-phoenix-client/) [](https://arize-phoenix.readthedocs.io/projects/client/en/latest/index.html) | Lightweight client for interacting with the Phoenix server via its OpenAPI REST interface |
|
|
208
|
+
| [arize-phoenix-evals](https://github.com/Arize-ai/phoenix/tree/main/packages/phoenix-evals) | [](https://pypi.org/project/arize-phoenix-evals/) [](https://arize-phoenix.readthedocs.io/projects/evals/en/latest/index.html) | Tooling to evaluate LLM applications including RAG relevance, answer relevance, and more |
|
|
209
|
+
| [@arizeai/phoenix-client](https://github.com/Arize-ai/phoenix/tree/main/js/packages/phoenix-client) | [](https://www.npmjs.com/package/@arizeai/phoenix-client) [](https://arize-ai.github.io/phoenix/) | Client for the Arize Phoenix API |
|
|
210
|
+
| [@arizeai/phoenix-evals](https://github.com/Arize-ai/phoenix/tree/main/js/packages/phoenix-evals) | [](https://www.npmjs.com/package/@arizeai/phoenix-evals) [](https://arize-ai.github.io/phoenix/) | TypeScript evaluation library for LLM applications (alpha release) |
|
|
211
|
+
| [@arizeai/phoenix-mcp](https://github.com/Arize-ai/phoenix/tree/main/js/packages/phoenix-mcp) | [](https://www.npmjs.com/package/@arizeai/phoenix-mcp) [](./js/packages/phoenix-mcp/README.md) | MCP server implementation for Arize Phoenix providing unified interface to Phoenix's capabilities |
|
|
212
212
|
|
|
213
213
|
## Tracing Integrations
|
|
214
214
|
|
|
@@ -256,17 +256,17 @@ Phoenix is built on top of OpenTelemetry and is vendor, language, and framework
|
|
|
256
256
|
| Integration | Package | Version Badge |
|
|
257
257
|
| --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
258
258
|
| [LangChain4j](https://github.com/Arize-ai/openinference/tree/main/java/instrumentation/openinference-instrumentation-langchain4j) | `openinference-instrumentation-langchain4j` | [](https://central.sonatype.com/artifact/com.arize/openinference-instrumentation-langchain4j) |
|
|
259
|
-
| [SpringAI](https://central.sonatype.com/artifact/com.arize/openinference-instrumentation-springAI)
|
|
259
|
+
| [SpringAI](https://central.sonatype.com/artifact/com.arize/openinference-instrumentation-springAI) | `openinference-instrumentation-springAI` | [](https://central.sonatype.com/artifact/com.arize/openinference-instrumentation-springAI) |
|
|
260
260
|
|
|
261
261
|
### Platforms
|
|
262
262
|
|
|
263
|
-
| Platform | Description | Docs
|
|
264
|
-
| -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
|
|
265
|
-
| [BeeAI](https://docs.beeai.dev/observability/agents-traceability) | AI agent framework with built-in observability | [Integration Guide](https://docs.beeai.dev/observability/agents-traceability)
|
|
266
|
-
| [Dify](https://docs.dify.ai/en/guides/monitoring/integrate-external-ops-tools/integrate-phoenix) | Open-source LLM app development platform | [Integration Guide](https://docs.dify.ai/en/guides/monitoring/integrate-external-ops-tools/integrate-phoenix)
|
|
267
|
-
| [Envoy AI Gateway](https://github.com/envoyproxy/ai-gateway)
|
|
268
|
-
| [LangFlow](https://arize.com/docs/phoenix/tracing/integrations-tracing/langflow) | Visual framework for building multi-agent and RAG applications | [Integration Guide](https://arize.com/docs/phoenix/tracing/integrations-tracing/langflow)
|
|
269
|
-
| [LiteLLM Proxy](https://docs.litellm.ai/docs/observability/phoenix_integration#using-with-litellm-proxy) | Proxy server for LLMs | [Integration Guide](https://docs.litellm.ai/docs/observability/phoenix_integration#using-with-litellm-proxy)
|
|
263
|
+
| Platform | Description | Docs |
|
|
264
|
+
| -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
265
|
+
| [BeeAI](https://docs.beeai.dev/observability/agents-traceability) | AI agent framework with built-in observability | [Integration Guide](https://docs.beeai.dev/observability/agents-traceability) |
|
|
266
|
+
| [Dify](https://docs.dify.ai/en/guides/monitoring/integrate-external-ops-tools/integrate-phoenix) | Open-source LLM app development platform | [Integration Guide](https://docs.dify.ai/en/guides/monitoring/integrate-external-ops-tools/integrate-phoenix) |
|
|
267
|
+
| [Envoy AI Gateway](https://github.com/envoyproxy/ai-gateway) | AI Gateway built on Envoy Proxy for AI workloads | [Integration Guide](https://github.com/envoyproxy/ai-gateway/tree/main/cmd/aigw#opentelemetry-setup-with-phoenix) |
|
|
268
|
+
| [LangFlow](https://arize.com/docs/phoenix/tracing/integrations-tracing/langflow) | Visual framework for building multi-agent and RAG applications | [Integration Guide](https://arize.com/docs/phoenix/tracing/integrations-tracing/langflow) |
|
|
269
|
+
| [LiteLLM Proxy](https://docs.litellm.ai/docs/observability/phoenix_integration#using-with-litellm-proxy) | Proxy server for LLMs | [Integration Guide](https://docs.litellm.ai/docs/observability/phoenix_integration#using-with-litellm-proxy) |
|
|
270
270
|
|
|
271
271
|
## Community
|
|
272
272
|
|
|
@@ -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=
|
|
9
|
+
phoenix/version.py,sha256=wTfhUKXJGuW6Cd3BIdlJ2UX7HyglNmvKt33CteybMx8,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
|
|
@@ -56,9 +56,9 @@ phoenix/db/types/db_models.py,sha256=nMSd9gWHwObnVO3_slztlHqoeh04czS-Jxu-omS6M6E
|
|
|
56
56
|
phoenix/db/types/identifier.py,sha256=Opr3_1di6e5ncrBDn30WfBSr-jN_VGBnkkA4BMuSoyc,244
|
|
57
57
|
phoenix/db/types/model_provider.py,sha256=zKYGcEQqbAxtPwnq5dL0fYPgDC8nrh_ABLBMR94___4,237
|
|
58
58
|
phoenix/db/types/token_price_customization.py,sha256=LAb8IwyFJGDCje7CvcPcxNp4NOU8si5hSYaf1fyi624,857
|
|
59
|
-
phoenix/db/types/trace_retention.py,sha256=
|
|
59
|
+
phoenix/db/types/trace_retention.py,sha256=Y97xfqNa4AO2j6RhhUJIbO6duQ1oX7Vu5bC9laydf1g,9899
|
|
60
60
|
phoenix/experiments/__init__.py,sha256=6JGwgUd7xCbGpuHqYZlsmErmYvVgv7N_j43bn3dUqsk,123
|
|
61
|
-
phoenix/experiments/functions.py,sha256=
|
|
61
|
+
phoenix/experiments/functions.py,sha256=7qFTJ2jYXNyXkWvO66RJuCybNVkUdiwxjGtcoPyqhDs,41285
|
|
62
62
|
phoenix/experiments/tracing.py,sha256=X-wlgbWEzP1oHkLmjop3fGjONo6JK5a0kPXc9YYD014,2856
|
|
63
63
|
phoenix/experiments/types.py,sha256=O4vvm9WOp0fevTDobStXEJpFKn3acveXgsRClxlnzCM,23477
|
|
64
64
|
phoenix/experiments/utils.py,sha256=MZ1-OnTcavk_KUtbfGqt55Fk9TGtJpYG_K71WsN-zDk,785
|
|
@@ -124,7 +124,7 @@ phoenix/server/api/dataloaders/average_experiment_run_latency.py,sha256=_wEcC47z
|
|
|
124
124
|
phoenix/server/api/dataloaders/dataset_example_revisions.py,sha256=xF7M2dg3UmjhdCrscnztCIBBI0cg3RF48IIqvilpc18,4623
|
|
125
125
|
phoenix/server/api/dataloaders/dataset_example_spans.py,sha256=z_MFquqAcJ9wat7BBp7MVeJ9BYuu2EZEdaog52iWDno,1390
|
|
126
126
|
phoenix/server/api/dataloaders/document_evaluation_summaries.py,sha256=9fdROnzp-mymggHwNvpRkCk93LUFxxLy55-j3HP_2HY,5565
|
|
127
|
-
phoenix/server/api/dataloaders/document_evaluations.py,sha256=
|
|
127
|
+
phoenix/server/api/dataloaders/document_evaluations.py,sha256=1bpBDydd-9YvhgkNoE5w-FGrjtnjUztcnjZTdMAazws,1072
|
|
128
128
|
phoenix/server/api/dataloaders/document_retrieval_metrics.py,sha256=37EcAW7oYQuWYHMDHb0wcqbWj9lhSskvzDO7NJbT5Js,4136
|
|
129
129
|
phoenix/server/api/dataloaders/experiment_annotation_summaries.py,sha256=CFVj7DwFYj330FLU5w3zEr12AGUX1e8ZX0X5buxMuEk,5643
|
|
130
130
|
phoenix/server/api/dataloaders/experiment_error_rates.py,sha256=06IZF07qt2y167DBM49QkSNdnphPArhcsgYFcunaL-U,1992
|
|
@@ -257,18 +257,18 @@ phoenix/server/api/routers/oauth2.py,sha256=rPcKFvfijzBYLjfwbCNzCn0ihn4wGWh4xh6B
|
|
|
257
257
|
phoenix/server/api/routers/utils.py,sha256=M41BoH-fl37izhRuN2aX7lWm7jOC20A_3uClv9TVUUY,583
|
|
258
258
|
phoenix/server/api/routers/v1/__init__.py,sha256=_CxVCs26dPuC2KygV3VzYqmoAECeFwiSTava9mxIJTE,2790
|
|
259
259
|
phoenix/server/api/routers/v1/annotation_configs.py,sha256=xp5lJmKYlRsINCUrRD9-lTAElw2v4hdFndS5BWrxICA,16048
|
|
260
|
-
phoenix/server/api/routers/v1/annotations.py,sha256=
|
|
260
|
+
phoenix/server/api/routers/v1/annotations.py,sha256=V_Cm_XOJaSVpMsTCfxBd1H39sk17b2y6Lyk5qwwDHvI,11433
|
|
261
261
|
phoenix/server/api/routers/v1/datasets.py,sha256=9iPORLmbOrPKgUUcRDMs6ZczSIz7hvc6bngJy3IbdR0,38331
|
|
262
|
-
phoenix/server/api/routers/v1/documents.py,sha256=
|
|
262
|
+
phoenix/server/api/routers/v1/documents.py,sha256=iA_vYU6_p2-pazh_Rp930kiOsiHYFIPPqsZSSXwPgVI,5733
|
|
263
263
|
phoenix/server/api/routers/v1/evaluations.py,sha256=aBrPO-xCAWyTxydaHq7W2wQFm65k89uVR-H3VWsd6WQ,13062
|
|
264
264
|
phoenix/server/api/routers/v1/experiment_evaluations.py,sha256=DZ3UK9OoYKElpRcEER7559-KiAqWr-1IXpZ27FbfP3k,5249
|
|
265
|
-
phoenix/server/api/routers/v1/experiment_runs.py,sha256=
|
|
265
|
+
phoenix/server/api/routers/v1/experiment_runs.py,sha256=H-WSEFuMSr-pDzP9IMsGktqMHMwMAhen6FSfYYu3ZZg,8372
|
|
266
266
|
phoenix/server/api/routers/v1/experiments.py,sha256=hIBecGACzGZEgl93ap_JV52pUv-Ij03QJMRxQhBlktI,20611
|
|
267
267
|
phoenix/server/api/routers/v1/models.py,sha256=p3gJN-9SWiUYTUTft4bZMsZVCBNTb4nN1Foy68eRZzQ,1997
|
|
268
268
|
phoenix/server/api/routers/v1/projects.py,sha256=XR6uJxHXXtC1q8LNyS9W6iaj440sv1OKCu-OSBfxEys,12824
|
|
269
269
|
phoenix/server/api/routers/v1/prompts.py,sha256=chRYcLkOYDJdJfVZVukVTUyIRnLPvsJCg41CuPxOIU8,26695
|
|
270
|
-
phoenix/server/api/routers/v1/spans.py,sha256=
|
|
271
|
-
phoenix/server/api/routers/v1/traces.py,sha256
|
|
270
|
+
phoenix/server/api/routers/v1/spans.py,sha256=9xWj5RZEGCjOUVCx9bl-tHdQrIS6VvaUROfo3ROg7J4,47583
|
|
271
|
+
phoenix/server/api/routers/v1/traces.py,sha256=-_g-Imy31J_jWyCOMIOAHMEdMB6KxeLRNW56r9-6REI,9849
|
|
272
272
|
phoenix/server/api/routers/v1/users.py,sha256=eO8zMtGU33Td2_G1l9D7Z0a4CG1CwBUCj_Z9z2uk7wg,12089
|
|
273
273
|
phoenix/server/api/routers/v1/utils.py,sha256=oXIOGPzPTkE0ZWUTRCoRIQQ7wTzoSwtWFaUSjlGBqts,4960
|
|
274
274
|
phoenix/server/api/types/Annotation.py,sha256=gsl8CwjIbDUbZRj4d9USwZ_w_Tkz4i7zuZh9ftV80jA,1132
|
|
@@ -285,9 +285,10 @@ phoenix/server/api/types/CostBreakdown.py,sha256=yw9dlb0blGIB_dWNP8yEvDHJztHjpiV
|
|
|
285
285
|
phoenix/server/api/types/CreateDatasetPayload.py,sha256=R-6zCmuD0f76RU9Giu78xwTHlASQs6Aq8yzvX1Kxc3g,140
|
|
286
286
|
phoenix/server/api/types/CronExpression.py,sha256=R7oxuSSX_eTUHQWaoaSueQqWDmkkHr5dBKRN6q-6ROk,331
|
|
287
287
|
phoenix/server/api/types/DataQualityMetric.py,sha256=Aieg3bHeBFaAf4mqeRcH1zT04sXAtQD8ATSHJt7FaBQ,1538
|
|
288
|
-
phoenix/server/api/types/Dataset.py,sha256=
|
|
288
|
+
phoenix/server/api/types/Dataset.py,sha256=OvCgbqqNF-bj0iaQldIeEfZiMjyXGFsozIIBsbJJwq4,12648
|
|
289
289
|
phoenix/server/api/types/DatasetExample.py,sha256=_9byxGpXfYb-hmFMUJeG7Bw1wsRKSJaHwF2IPAbFpFw,3115
|
|
290
290
|
phoenix/server/api/types/DatasetExampleRevision.py,sha256=c-jWR6dTguEZTm54IMlFr0Ic84I3nefyDnZb7nF5hnI,874
|
|
291
|
+
phoenix/server/api/types/DatasetExperimentAnnotationSummary.py,sha256=EVXz6zfbdYsU5SZ6FUrAA_VQqQCnBE_mbKgmAmFoDLI,195
|
|
291
292
|
phoenix/server/api/types/DatasetValues.py,sha256=7VbCOLlzOXpZN80-zYF2UGuafRcPsZF-8WQNc0YsKFc,1119
|
|
292
293
|
phoenix/server/api/types/DatasetVersion.py,sha256=NnDriqQUE20N_Jhyu3-IxHWJQE9wmdHEJIQAKyTVJpo,302
|
|
293
294
|
phoenix/server/api/types/Dimension.py,sha256=VjW6kOMhFslGSSHlsylpF1hYY3wuhopC2LM2eOcIhRI,10665
|
|
@@ -295,11 +296,11 @@ phoenix/server/api/types/DimensionDataType.py,sha256=o0QQRpUzgXbhd10drR2LthxrjB8
|
|
|
295
296
|
phoenix/server/api/types/DimensionShape.py,sha256=LNsRt3Uyx1OmwMa5EXk1JGRXPLVV2EEgYXz-6wnLJn4,562
|
|
296
297
|
phoenix/server/api/types/DimensionType.py,sha256=JLikZUBVqbHlUWcYYd8d60gB1_hmAcuFuZZsjCXpIwc,801
|
|
297
298
|
phoenix/server/api/types/DimensionWithValue.py,sha256=4_koirnDrZBBdFkIWka2f-OeqZ6IzQXwqz3ccjdgHrc,484
|
|
299
|
+
phoenix/server/api/types/DocumentAnnotation.py,sha256=CMNcODXnKYzAUBITp_iYOoCGpXPEFGnelxmWySqDyn4,3076
|
|
298
300
|
phoenix/server/api/types/DocumentEvaluationSummary.py,sha256=dx4Btlfw9_XsfmibjfWvMOvUfrvr9oGJq8jYmIL2o-Q,3494
|
|
299
301
|
phoenix/server/api/types/DocumentRetrievalMetrics.py,sha256=amkpC3H5IU5-9GvO0telpbq00m6lIcv_2v446OpwFwc,1822
|
|
300
302
|
phoenix/server/api/types/EmbeddingDimension.py,sha256=AYvpZ1nWINAgN4BAZsA_xI_2TNFK6h5jmqzvkPs651M,19428
|
|
301
303
|
phoenix/server/api/types/EmbeddingMetadata.py,sha256=fJvNNYCbkf3SJalArLy9rcBq9Uj1SNac60zjqe1PFnM,461
|
|
302
|
-
phoenix/server/api/types/Evaluation.py,sha256=qkMmq5G9pgwUNOPSTRwR-nNAoqLT3LlXrq7O8cAgXQ8,1356
|
|
303
304
|
phoenix/server/api/types/EvaluationSummary.py,sha256=vILYejnfPvMwWEXOwhQZsANvYe3AdO2OkMR2rcgp1H4,1512
|
|
304
305
|
phoenix/server/api/types/Event.py,sha256=iYt_Jx1Roioo0vZ0iPeJTHcTu6NSm4ilVMJ-IMUHAKk,3970
|
|
305
306
|
phoenix/server/api/types/EventMetadata.py,sha256=-J0tYF9eZTHwCjwxQHY7Gckr2_MNW5OoWT1mydweZNM,635
|
|
@@ -338,7 +339,7 @@ phoenix/server/api/types/ScalarDriftMetricEnum.py,sha256=IUAcRPpgL41WdoIgK6cNk2T
|
|
|
338
339
|
phoenix/server/api/types/Segments.py,sha256=vT2v0efoa5cuBKxLtxTnsUP5YJJCZfTloM71Spu0tMI,2915
|
|
339
340
|
phoenix/server/api/types/ServerStatus.py,sha256=t92OHuVhK9DXDk2vsBuHceQNKqYGpHwUp8DNGKz2wOk,88
|
|
340
341
|
phoenix/server/api/types/SortDir.py,sha256=OUpXhlCzCxPoXSDkJJygEs9Rw9pMymfaZUG5zPTrw4Y,152
|
|
341
|
-
phoenix/server/api/types/Span.py,sha256=
|
|
342
|
+
phoenix/server/api/types/Span.py,sha256=wJEEReo38Qsc0nFuBF0LDq9kcfGwmYerA86FXC4GqzE,32130
|
|
342
343
|
phoenix/server/api/types/SpanAnnotation.py,sha256=uPWu7Z8rmpfKhaaxbged4_o00pPCR3nkn7Gji9vB8jY,1959
|
|
343
344
|
phoenix/server/api/types/SpanCostDetailSummaryEntry.py,sha256=RXAdOC6MFyR9mwaoj8lMMdI3_9r3z6mR2izJvlsj12U,252
|
|
344
345
|
phoenix/server/api/types/SpanCostSummary.py,sha256=wo03FCMcFzB5m4P5kvA5jzi9ACLbht38ozQbDJUh94g,357
|
|
@@ -350,7 +351,7 @@ phoenix/server/api/types/TokenPrice.py,sha256=OyCZgXCKDIihmDalHvkUDvhvl2Vsxx1J2U
|
|
|
350
351
|
phoenix/server/api/types/TokenUsage.py,sha256=aeMPwEDqu8MWT2Jc5sq6Sfb_7kcR_KTzZi6UB9OK7Yg,207
|
|
351
352
|
phoenix/server/api/types/ToolDefinition.py,sha256=T6UH2vcbuPBDy7jKYOqMth2NdqxMPgDBf11Tpbt5Yb8,187
|
|
352
353
|
phoenix/server/api/types/Trace.py,sha256=iaSAicxMHTrnUTYxNfMwFMglVeptqu7nF_AHS6k-QGw,9718
|
|
353
|
-
phoenix/server/api/types/TraceAnnotation.py,sha256=
|
|
354
|
+
phoenix/server/api/types/TraceAnnotation.py,sha256=NAZ5HXH31x6zjXlh-1CUiXjbiCo0iF6hqIrgts2h3Lo,2022
|
|
354
355
|
phoenix/server/api/types/UMAPPoints.py,sha256=49sWnxjcAJKRzqUY71Fa0tOPti5XjIIFT5cSg6oNu_U,1650
|
|
355
356
|
phoenix/server/api/types/User.py,sha256=20q4K_dwWHKdCTLFOmpdbt_OjdGv-98z2dHhwh7RmnI,2412
|
|
356
357
|
phoenix/server/api/types/UserApiKey.py,sha256=EcsPNxV_PtgpqwA_bPTj_aRYt15l6X24YDy20hUPywU,1251
|
|
@@ -364,7 +365,7 @@ phoenix/server/cost_tracking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
|
364
365
|
phoenix/server/cost_tracking/cost_details_calculator.py,sha256=Tt0YcuLhgPuXKWJemWVmYQfG0xQUvH4VziIj6KcDnoA,8945
|
|
365
366
|
phoenix/server/cost_tracking/cost_model_lookup.py,sha256=jhtVdnQBzrTUHeOGPWgOebk-Io5hpJ1vAgWOu8ojeJ4,6801
|
|
366
367
|
phoenix/server/cost_tracking/helpers.py,sha256=Pk6ECjnYreTxrldtRwxnwFcxIPVsvDq_yAwDA_spkOc,2122
|
|
367
|
-
phoenix/server/cost_tracking/model_cost_manifest.json,sha256=
|
|
368
|
+
phoenix/server/cost_tracking/model_cost_manifest.json,sha256=hOe6WLOd4t99iMCwCVbOya9kERKb7Ci_NR2opiNQY5M,65570
|
|
368
369
|
phoenix/server/cost_tracking/regex_specificity.py,sha256=9kqWuQ68C-hlwW25hr7BhFlRt5y2Nnpy0Ax3n9UN6Xk,11622
|
|
369
370
|
phoenix/server/cost_tracking/token_cost_calculator.py,sha256=2JEZnvusx2-xbhp8krp9EarjWuyGH2KO4e-ZwJX-K0s,1598
|
|
370
371
|
phoenix/server/daemons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -393,10 +394,10 @@ phoenix/server/static/apple-touch-icon-76x76.png,sha256=CT_xT12I0u2i0WU8JzBZBuOQ
|
|
|
393
394
|
phoenix/server/static/apple-touch-icon.png,sha256=fOfpjqGpWYbJ0eAurKsyoZP1EAs6ZVooBJ_SGk2ZkDs,3801
|
|
394
395
|
phoenix/server/static/favicon.ico,sha256=bY0vvCKRftemZfPShwZtE93DiiQdaYaozkPGwNFr6H8,34494
|
|
395
396
|
phoenix/server/static/modernizr.js,sha256=mvK-XtkNqjOral-QvzoqsyOMECXIMu5BQwSVN_wcU9c,2564
|
|
396
|
-
phoenix/server/static/.vite/manifest.json,sha256=
|
|
397
|
-
phoenix/server/static/assets/components-
|
|
398
|
-
phoenix/server/static/assets/index-
|
|
399
|
-
phoenix/server/static/assets/pages-
|
|
397
|
+
phoenix/server/static/.vite/manifest.json,sha256=SftlYsrBTWT-YgHAEYzi01rPZZ4ICS4LX28rKBTiEAs,2328
|
|
398
|
+
phoenix/server/static/assets/components-Cs9c4Nxp.js,sha256=5e_FqxJ4cxQ2lSztbWI9bXdUd0tbXNZjOK_basUj_2s,664533
|
|
399
|
+
phoenix/server/static/assets/index-D1FDMBMV.js,sha256=sZ5WMvooPARvbjfKW_pMVOlJVuqcBI8tTZ8iVUGU4s8,63396
|
|
400
|
+
phoenix/server/static/assets/pages-Cbj9SjBx.js,sha256=Cc1SZLF_HyhwRlxlK_Zsmxmjsb_jFCZeObBG2E6Luns,1272157
|
|
400
401
|
phoenix/server/static/assets/vendor-CqDb5u4o.css,sha256=zIyFiNJKxMaQk8AvtLgt1rR01oO10d1MFndSDKH9Clw,5517
|
|
401
402
|
phoenix/server/static/assets/vendor-RdRDaQiR.js,sha256=oTxLetZZXJ20yoKNAYExto9V73y8X5zjddWV46K9CWM,2595492
|
|
402
403
|
phoenix/server/static/assets/vendor-arizeai-DsYDNOqt.js,sha256=0HIkPJXbKTh85nqphdAXYeStRzdaim0IQxRXiXxa21U,121514
|
|
@@ -418,7 +419,7 @@ phoenix/trace/evaluation_conventions.py,sha256=t8jydM3U0-T5YpiQKRJ3tWdWGlHtzKytt
|
|
|
418
419
|
phoenix/trace/exporter.py,sha256=bUXh8fjJIbHurrnt4bAm-cCWqUN5FqNsIc8DZzzklkQ,4695
|
|
419
420
|
phoenix/trace/fixtures.py,sha256=1c7fsyvmxC53Fib9T_Qxp_Ly3OZdDbkLQ0XpFzikEjk,20298
|
|
420
421
|
phoenix/trace/otel.py,sha256=RJSbAuzS4KBS0t-fntXQaaYwv7FmIXRMrw65DI67z8k,10622
|
|
421
|
-
phoenix/trace/projects.py,sha256=
|
|
422
|
+
phoenix/trace/projects.py,sha256=2wVg_UaNiXuhn60qJhgqJiaQ0OnbOWMnB10QeTGZGwQ,2420
|
|
422
423
|
phoenix/trace/schemas.py,sha256=Su6e567Bei9oo6PsWO2srTcPAj9C2bMgbGtx64Sgqeg,6332
|
|
423
424
|
phoenix/trace/span_evaluations.py,sha256=x3nye9r2SQk1mrR3N05YbuWsgUKpMWwTRBtJTDBSj3Y,13156
|
|
424
425
|
phoenix/trace/span_json_decoder.py,sha256=J1_oDViuUoC4vxPg61U4EOZC1uEMcCzoj-kVjOFEE8k,3224
|
|
@@ -443,9 +444,9 @@ phoenix/utilities/project.py,sha256=auVpARXkDb-JgeX5f2aStyFIkeKvGwN9l7qrFeJMVxI,
|
|
|
443
444
|
phoenix/utilities/re.py,sha256=6YyUWIkv0zc2SigsxfOWIHzdpjKA_TZo2iqKq7zJKvw,2081
|
|
444
445
|
phoenix/utilities/span_store.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
445
446
|
phoenix/utilities/template_formatters.py,sha256=gh9PJD6WEGw7TEYXfSst1UR4pWWwmjxMLrDVQ_CkpkQ,2779
|
|
446
|
-
arize_phoenix-11.
|
|
447
|
-
arize_phoenix-11.
|
|
448
|
-
arize_phoenix-11.
|
|
449
|
-
arize_phoenix-11.
|
|
450
|
-
arize_phoenix-11.
|
|
451
|
-
arize_phoenix-11.
|
|
447
|
+
arize_phoenix-11.32.0.dist-info/METADATA,sha256=l937gONO1AEiuhgulspeCuLVxPdy-gmLrzzd_ZdP0Ms,32877
|
|
448
|
+
arize_phoenix-11.32.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
449
|
+
arize_phoenix-11.32.0.dist-info/entry_points.txt,sha256=Pgpn8Upxx9P8z8joPXZWl2LlnAlGc3gcQoVchb06X1Q,94
|
|
450
|
+
arize_phoenix-11.32.0.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
|
|
451
|
+
arize_phoenix-11.32.0.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
|
|
452
|
+
arize_phoenix-11.32.0.dist-info/RECORD,,
|
|
@@ -199,7 +199,7 @@ class TraceRetentionCronExpression(RootModel[str]):
|
|
|
199
199
|
|
|
200
200
|
def _parse_field(field: str, min_val: int, max_val: int) -> set[int]:
|
|
201
201
|
"""
|
|
202
|
-
|
|
202
|
+
Parses a cron field and returns the set of matching values.
|
|
203
203
|
|
|
204
204
|
Args:
|
|
205
205
|
field (str): The cron field to parse
|
phoenix/experiments/functions.py
CHANGED
|
@@ -109,6 +109,64 @@ def _phoenix_clients() -> tuple[httpx.Client, httpx.AsyncClient]:
|
|
|
109
109
|
)
|
|
110
110
|
|
|
111
111
|
|
|
112
|
+
def _get_all_experiment_runs(
|
|
113
|
+
client: httpx.Client,
|
|
114
|
+
experiment_id: str,
|
|
115
|
+
page_size: int = 50,
|
|
116
|
+
) -> list[ExperimentRun]:
|
|
117
|
+
"""
|
|
118
|
+
Fetch all experiment runs using pagination to handle large datasets.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
client: The HTTP client to use for requests.
|
|
122
|
+
experiment_id: The ID of the experiment.
|
|
123
|
+
page_size: Number of runs to fetch per page. Defaults to 50.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
List of all experiment runs as ExperimentRun objects.
|
|
127
|
+
"""
|
|
128
|
+
all_runs: list[dict[str, Any]] = []
|
|
129
|
+
cursor = None
|
|
130
|
+
|
|
131
|
+
while True:
|
|
132
|
+
params: dict[str, Any] = {"limit": page_size}
|
|
133
|
+
if cursor:
|
|
134
|
+
params["cursor"] = cursor
|
|
135
|
+
|
|
136
|
+
try:
|
|
137
|
+
response = client.get(
|
|
138
|
+
f"v1/experiments/{experiment_id}/runs",
|
|
139
|
+
params=params,
|
|
140
|
+
)
|
|
141
|
+
response.raise_for_status()
|
|
142
|
+
data = response.json()
|
|
143
|
+
|
|
144
|
+
runs = data["data"]
|
|
145
|
+
all_runs.extend(runs)
|
|
146
|
+
|
|
147
|
+
# Check if there are more pages
|
|
148
|
+
cursor = data.get("next_cursor")
|
|
149
|
+
if not cursor:
|
|
150
|
+
break
|
|
151
|
+
|
|
152
|
+
except HTTPStatusError as e:
|
|
153
|
+
if e.response.status_code == 404:
|
|
154
|
+
# Experiment doesn't exist - treat as empty result
|
|
155
|
+
break
|
|
156
|
+
else:
|
|
157
|
+
raise
|
|
158
|
+
|
|
159
|
+
# Convert dicts to ExperimentRun objects
|
|
160
|
+
experiment_runs: list[ExperimentRun] = []
|
|
161
|
+
for run in all_runs:
|
|
162
|
+
# Parse datetime strings
|
|
163
|
+
run["start_time"] = datetime.fromisoformat(run["start_time"])
|
|
164
|
+
run["end_time"] = datetime.fromisoformat(run["end_time"])
|
|
165
|
+
experiment_runs.append(ExperimentRun.from_dict(run))
|
|
166
|
+
|
|
167
|
+
return experiment_runs
|
|
168
|
+
|
|
169
|
+
|
|
112
170
|
Evaluators: TypeAlias = Union[
|
|
113
171
|
ExperimentEvaluator,
|
|
114
172
|
Sequence[ExperimentEvaluator],
|
|
@@ -231,7 +289,7 @@ def run_experiment(
|
|
|
231
289
|
}
|
|
232
290
|
if not dry_run:
|
|
233
291
|
experiment_response = sync_client.post(
|
|
234
|
-
f"
|
|
292
|
+
f"v1/datasets/{normalized_dataset.id}/experiments",
|
|
235
293
|
json=payload,
|
|
236
294
|
)
|
|
237
295
|
experiment_response.raise_for_status()
|
|
@@ -303,7 +361,7 @@ def run_experiment(
|
|
|
303
361
|
try:
|
|
304
362
|
# Try to create the run directly
|
|
305
363
|
resp = sync_client.post(
|
|
306
|
-
f"
|
|
364
|
+
f"v1/experiments/{experiment.id}/runs", json=jsonify(exp_run)
|
|
307
365
|
)
|
|
308
366
|
resp.raise_for_status()
|
|
309
367
|
exp_run = replace(exp_run, id=resp.json()["data"]["id"])
|
|
@@ -381,7 +439,7 @@ def run_experiment(
|
|
|
381
439
|
try:
|
|
382
440
|
# Try to create the run directly
|
|
383
441
|
resp = sync_client.post(
|
|
384
|
-
f"
|
|
442
|
+
f"v1/experiments/{experiment.id}/runs", json=jsonify(exp_run)
|
|
385
443
|
)
|
|
386
444
|
resp.raise_for_status()
|
|
387
445
|
exp_run = replace(exp_run, id=resp.json()["data"]["id"])
|
|
@@ -420,7 +478,7 @@ def run_experiment(
|
|
|
420
478
|
None,
|
|
421
479
|
functools.partial(
|
|
422
480
|
sync_client.post,
|
|
423
|
-
url=f"
|
|
481
|
+
url=f"v1/experiments/{experiment.id}/runs",
|
|
424
482
|
json=jsonify(exp_run),
|
|
425
483
|
),
|
|
426
484
|
)
|
|
@@ -498,7 +556,7 @@ def run_experiment(
|
|
|
498
556
|
None,
|
|
499
557
|
functools.partial(
|
|
500
558
|
sync_client.post,
|
|
501
|
-
url=f"
|
|
559
|
+
url=f"v1/experiments/{experiment.id}/runs",
|
|
502
560
|
json=jsonify(exp_run),
|
|
503
561
|
),
|
|
504
562
|
)
|
|
@@ -548,13 +606,7 @@ def run_experiment(
|
|
|
548
606
|
|
|
549
607
|
# Get the final state of runs from the database
|
|
550
608
|
if not dry_run:
|
|
551
|
-
|
|
552
|
-
task_runs = []
|
|
553
|
-
for run in all_runs:
|
|
554
|
-
# Parse datetime strings
|
|
555
|
-
run["start_time"] = datetime.fromisoformat(run["start_time"])
|
|
556
|
-
run["end_time"] = datetime.fromisoformat(run["end_time"])
|
|
557
|
-
task_runs.append(ExperimentRun.from_dict(run))
|
|
609
|
+
task_runs = _get_all_experiment_runs(sync_client, experiment.id)
|
|
558
610
|
|
|
559
611
|
# Check if we got all expected runs
|
|
560
612
|
expected_runs = len(normalized_dataset.examples) * repetitions
|
|
@@ -613,16 +665,14 @@ def evaluate_experiment(
|
|
|
613
665
|
else:
|
|
614
666
|
dataset = Dataset.from_dict(
|
|
615
667
|
sync_client.get(
|
|
616
|
-
f"
|
|
668
|
+
f"v1/datasets/{dataset_id}/examples",
|
|
617
669
|
params={"version_id": str(dataset_version_id)},
|
|
618
670
|
).json()["data"]
|
|
619
671
|
)
|
|
620
672
|
if not dataset.examples:
|
|
621
673
|
raise ValueError(f"Dataset has no examples: {dataset_id=}, {dataset_version_id=}")
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
for exp_run in sync_client.get(f"/v1/experiments/{experiment.id}/runs").json()["data"]
|
|
625
|
-
}
|
|
674
|
+
all_runs = _get_all_experiment_runs(sync_client, experiment.id)
|
|
675
|
+
experiment_runs = {exp_run.id: exp_run for exp_run in all_runs}
|
|
626
676
|
if not experiment_runs:
|
|
627
677
|
raise ValueError("Experiment has not been run")
|
|
628
678
|
params = ExperimentParameters(n_examples=len(dataset.examples))
|
|
@@ -715,7 +765,7 @@ def evaluate_experiment(
|
|
|
715
765
|
trace_id=_str_trace_id(span.get_span_context().trace_id), # type: ignore[no-untyped-call]
|
|
716
766
|
)
|
|
717
767
|
if not dry_run:
|
|
718
|
-
resp = sync_client.post("
|
|
768
|
+
resp = sync_client.post("v1/experiment_evaluations", json=jsonify(eval_run))
|
|
719
769
|
resp.raise_for_status()
|
|
720
770
|
eval_run = replace(eval_run, id=resp.json()["data"]["id"])
|
|
721
771
|
return eval_run
|
|
@@ -777,7 +827,7 @@ def evaluate_experiment(
|
|
|
777
827
|
None,
|
|
778
828
|
functools.partial(
|
|
779
829
|
sync_client.post,
|
|
780
|
-
url="
|
|
830
|
+
url="v1/experiment_evaluations",
|
|
781
831
|
json=jsonify(eval_run),
|
|
782
832
|
),
|
|
783
833
|
)
|
|
@@ -5,11 +5,10 @@ from strawberry.dataloader import DataLoader
|
|
|
5
5
|
from typing_extensions import TypeAlias
|
|
6
6
|
|
|
7
7
|
from phoenix.db import models
|
|
8
|
-
from phoenix.server.api.types.Evaluation import DocumentAnnotation
|
|
9
8
|
from phoenix.server.types import DbSessionFactory
|
|
10
9
|
|
|
11
10
|
Key: TypeAlias = int
|
|
12
|
-
Result: TypeAlias = list[DocumentAnnotation]
|
|
11
|
+
Result: TypeAlias = list[models.DocumentAnnotation]
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
class DocumentEvaluationsDataLoader(DataLoader[Key, Result]):
|
|
@@ -18,14 +17,12 @@ class DocumentEvaluationsDataLoader(DataLoader[Key, Result]):
|
|
|
18
17
|
self._db = db
|
|
19
18
|
|
|
20
19
|
async def _load_fn(self, keys: list[Key]) -> list[Result]:
|
|
21
|
-
|
|
20
|
+
document_annotations_by_id: defaultdict[Key, Result] = defaultdict(list)
|
|
22
21
|
mda = models.DocumentAnnotation
|
|
23
22
|
async with self._db() as session:
|
|
24
|
-
data = await session.stream_scalars(
|
|
25
|
-
select(mda).where(mda.span_rowid.in_(keys)).where(mda.annotator_kind == "LLM")
|
|
26
|
-
)
|
|
23
|
+
data = await session.stream_scalars(select(mda).where(mda.span_rowid.in_(keys)))
|
|
27
24
|
async for document_evaluation in data:
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
document_annotations_by_id[document_evaluation.span_rowid].append(
|
|
26
|
+
document_evaluation
|
|
30
27
|
)
|
|
31
|
-
return [
|
|
28
|
+
return [document_annotations_by_id[key] for key in keys]
|
|
@@ -1,32 +1,38 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from datetime import datetime
|
|
5
|
-
from typing import Literal, Optional
|
|
4
|
+
from datetime import datetime, timezone
|
|
5
|
+
from typing import Any, Literal, Optional
|
|
6
6
|
|
|
7
7
|
from fastapi import APIRouter, HTTPException, Path, Query
|
|
8
|
+
from pydantic import Field
|
|
8
9
|
from sqlalchemy import exists, select
|
|
9
10
|
from starlette.requests import Request
|
|
10
11
|
from starlette.status import HTTP_200_OK, HTTP_404_NOT_FOUND, HTTP_422_UNPROCESSABLE_ENTITY
|
|
11
12
|
from strawberry.relay import GlobalID
|
|
12
13
|
|
|
13
14
|
from phoenix.db import models
|
|
15
|
+
from phoenix.db.insertion.types import Precursors
|
|
16
|
+
from phoenix.server.api.routers.v1.models import V1RoutesBaseModel
|
|
14
17
|
from phoenix.server.api.types.SpanAnnotation import SpanAnnotation as SpanAnnotationNodeType
|
|
18
|
+
from phoenix.server.api.types.TraceAnnotation import TraceAnnotation as TraceAnnotationNodeType
|
|
15
19
|
from phoenix.server.api.types.User import User as UserNodeType
|
|
16
20
|
|
|
17
|
-
from .spans import SpanAnnotationData, SpanAnnotationResult
|
|
18
21
|
from .utils import PaginatedResponseBody, _get_project_by_identifier, add_errors_to_responses
|
|
19
22
|
|
|
20
23
|
logger = logging.getLogger(__name__)
|
|
21
24
|
|
|
22
25
|
SPAN_ANNOTATION_NODE_NAME = SpanAnnotationNodeType.__name__
|
|
26
|
+
TRACE_ANNOTATION_NODE_NAME = TraceAnnotationNodeType.__name__
|
|
27
|
+
MAX_TRACE_IDS = 1_000
|
|
23
28
|
USER_NODE_NAME = UserNodeType.__name__
|
|
24
29
|
MAX_SPAN_IDS = 1_000
|
|
30
|
+
MAX_SESSION_IDS = 1_000
|
|
25
31
|
|
|
26
32
|
router = APIRouter(tags=["annotations"])
|
|
27
33
|
|
|
28
34
|
|
|
29
|
-
class
|
|
35
|
+
class Annotation(V1RoutesBaseModel):
|
|
30
36
|
id: str
|
|
31
37
|
created_at: datetime
|
|
32
38
|
updated_at: datetime
|
|
@@ -34,10 +40,127 @@ class SpanAnnotation(SpanAnnotationData):
|
|
|
34
40
|
user_id: Optional[str]
|
|
35
41
|
|
|
36
42
|
|
|
43
|
+
class AnnotationResult(V1RoutesBaseModel):
|
|
44
|
+
label: Optional[str] = Field(default=None, description="The label assigned by the annotation")
|
|
45
|
+
score: Optional[float] = Field(default=None, description="The score assigned by the annotation")
|
|
46
|
+
explanation: Optional[str] = Field(
|
|
47
|
+
default=None, description="Explanation of the annotation result"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class AnnotationData(V1RoutesBaseModel):
|
|
52
|
+
name: str = Field(description="The name of the annotation")
|
|
53
|
+
annotator_kind: Literal["LLM", "CODE", "HUMAN"] = Field(
|
|
54
|
+
description="The kind of annotator used for the annotation"
|
|
55
|
+
)
|
|
56
|
+
result: Optional[AnnotationResult] = Field(
|
|
57
|
+
default=None, description="The result of the annotation"
|
|
58
|
+
)
|
|
59
|
+
metadata: Optional[dict[str, Any]] = Field(
|
|
60
|
+
default=None, description="Metadata for the annotation"
|
|
61
|
+
)
|
|
62
|
+
identifier: str = Field(
|
|
63
|
+
default="",
|
|
64
|
+
description=(
|
|
65
|
+
"The identifier of the annotation. "
|
|
66
|
+
"If provided, the annotation will be updated if it already exists."
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class SpanAnnotationData(AnnotationData):
|
|
72
|
+
span_id: str = Field(description="OpenTelemetry Span ID (hex format w/o 0x prefix)")
|
|
73
|
+
|
|
74
|
+
def as_precursor(self, *, user_id: Optional[int] = None) -> Precursors.SpanAnnotation:
|
|
75
|
+
return Precursors.SpanAnnotation(
|
|
76
|
+
datetime.now(timezone.utc),
|
|
77
|
+
self.span_id,
|
|
78
|
+
models.SpanAnnotation(
|
|
79
|
+
name=self.name,
|
|
80
|
+
annotator_kind=self.annotator_kind,
|
|
81
|
+
score=self.result.score if self.result else None,
|
|
82
|
+
label=self.result.label if self.result else None,
|
|
83
|
+
explanation=self.result.explanation if self.result else None,
|
|
84
|
+
metadata_=self.metadata or {},
|
|
85
|
+
identifier=self.identifier,
|
|
86
|
+
source="API",
|
|
87
|
+
user_id=user_id,
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class SpanAnnotation(SpanAnnotationData, Annotation):
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
|
|
37
96
|
class SpanAnnotationsResponseBody(PaginatedResponseBody[SpanAnnotation]):
|
|
38
97
|
pass
|
|
39
98
|
|
|
40
99
|
|
|
100
|
+
class SpanDocumentAnnotationData(AnnotationData):
|
|
101
|
+
span_id: str = Field(description="OpenTelemetry Span ID (hex format w/o 0x prefix)")
|
|
102
|
+
document_position: int = Field(
|
|
103
|
+
description="A 0 based index of the document. E.x. the first document during retrieval is 0"
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Precursor here means a value to add to a queue for processing async
|
|
107
|
+
def as_precursor(self, *, user_id: Optional[int] = None) -> Precursors.DocumentAnnotation:
|
|
108
|
+
return Precursors.DocumentAnnotation(
|
|
109
|
+
datetime.now(timezone.utc),
|
|
110
|
+
self.span_id,
|
|
111
|
+
self.document_position,
|
|
112
|
+
models.DocumentAnnotation(
|
|
113
|
+
name=self.name,
|
|
114
|
+
annotator_kind=self.annotator_kind,
|
|
115
|
+
document_position=self.document_position,
|
|
116
|
+
score=self.result.score if self.result else None,
|
|
117
|
+
label=self.result.label if self.result else None,
|
|
118
|
+
explanation=self.result.explanation if self.result else None,
|
|
119
|
+
metadata_=self.metadata or {},
|
|
120
|
+
identifier=self.identifier,
|
|
121
|
+
source="API",
|
|
122
|
+
user_id=user_id,
|
|
123
|
+
),
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class SpanDocumentAnnotation(SpanDocumentAnnotationData, Annotation):
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class SpanDocumentAnnotationsResponseBody(PaginatedResponseBody[SpanDocumentAnnotation]):
|
|
132
|
+
pass
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class TraceAnnotationData(AnnotationData):
|
|
136
|
+
trace_id: str = Field(description="OpenTelemetry Trace ID (hex format w/o 0x prefix)")
|
|
137
|
+
|
|
138
|
+
def as_precursor(self, *, user_id: Optional[int] = None) -> Precursors.TraceAnnotation:
|
|
139
|
+
return Precursors.TraceAnnotation(
|
|
140
|
+
datetime.now(timezone.utc),
|
|
141
|
+
self.trace_id,
|
|
142
|
+
models.TraceAnnotation(
|
|
143
|
+
name=self.name,
|
|
144
|
+
annotator_kind=self.annotator_kind,
|
|
145
|
+
score=self.result.score if self.result else None,
|
|
146
|
+
label=self.result.label if self.result else None,
|
|
147
|
+
explanation=self.result.explanation if self.result else None,
|
|
148
|
+
metadata_=self.metadata or {},
|
|
149
|
+
identifier=self.identifier,
|
|
150
|
+
source="API",
|
|
151
|
+
user_id=user_id,
|
|
152
|
+
),
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class TraceAnnotation(TraceAnnotationData, Annotation):
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class TraceAnnotationsResponseBody(PaginatedResponseBody[TraceAnnotation]):
|
|
161
|
+
pass
|
|
162
|
+
|
|
163
|
+
|
|
41
164
|
@router.get(
|
|
42
165
|
"/projects/{project_identifier}/span_annotations",
|
|
43
166
|
operation_id="listSpanAnnotationsBySpanIds",
|
|
@@ -164,7 +287,7 @@ async def list_span_annotations(
|
|
|
164
287
|
id=str(GlobalID(SPAN_ANNOTATION_NODE_NAME, str(anno.id))),
|
|
165
288
|
span_id=span_id,
|
|
166
289
|
name=anno.name,
|
|
167
|
-
result=
|
|
290
|
+
result=AnnotationResult(
|
|
168
291
|
label=anno.label,
|
|
169
292
|
score=anno.score,
|
|
170
293
|
explanation=anno.explanation,
|