arize-phoenix 4.20.1__py3-none-any.whl → 4.20.2__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-4.20.1.dist-info → arize_phoenix-4.20.2.dist-info}/METADATA +1 -1
- {arize_phoenix-4.20.1.dist-info → arize_phoenix-4.20.2.dist-info}/RECORD +19 -19
- phoenix/db/insertion/span.py +9 -0
- phoenix/db/migrations/versions/10460e46d750_datasets.py +28 -2
- phoenix/db/migrations/versions/3be8647b87d8_add_token_columns_to_spans_table.py +134 -0
- phoenix/db/migrations/versions/cf03bd6bae1d_init.py +28 -2
- phoenix/db/models.py +9 -1
- phoenix/server/api/dataloaders/token_counts.py +2 -7
- phoenix/server/api/input_types/SpanSort.py +3 -8
- phoenix/server/api/types/Span.py +3 -15
- phoenix/server/static/.vite/manifest.json +14 -14
- phoenix/server/static/assets/{components-CAummAJx.js → components-BSw2e1Zr.js} +108 -100
- phoenix/server/static/assets/{index-Cg5hdf3g.js → index-BYUFcdtx.js} +1 -1
- phoenix/server/static/assets/{pages-BU__X1UX.js → pages-p_fuED5k.js} +251 -237
- phoenix/server/static/assets/{vendor-arizeai-CkyzG9Wl.js → vendor-arizeai-CIETbKDq.js} +28 -28
- phoenix/version.py +1 -1
- phoenix/db/migrations/types.py +0 -29
- {arize_phoenix-4.20.1.dist-info → arize_phoenix-4.20.2.dist-info}/WHEEL +0 -0
- {arize_phoenix-4.20.1.dist-info → arize_phoenix-4.20.2.dist-info}/licenses/IP_NOTICE +0 -0
- {arize_phoenix-4.20.1.dist-info → arize_phoenix-4.20.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,7 +5,7 @@ phoenix/exceptions.py,sha256=n2L2KKuecrdflB9MsCdAYCiSEvGJptIsfRkXMoJle7A,169
|
|
|
5
5
|
phoenix/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
6
6
|
phoenix/services.py,sha256=aTxhcOA1pZHB6U-B3TEcp6fqDF5oT0xCUvEUNMZVTUQ,5175
|
|
7
7
|
phoenix/settings.py,sha256=cO-qgis_S27nHirTobYI9hHPfZH18R--WMmxNdsVUwc,273
|
|
8
|
-
phoenix/version.py,sha256=
|
|
8
|
+
phoenix/version.py,sha256=hh55rhGJPmETx024BaT0pa35ouf8-J2B1_CJUXY4XFg,23
|
|
9
9
|
phoenix/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
phoenix/core/embedding_dimension.py,sha256=zKGbcvwOXgLf-yrJBpQyKtd-LEOPRKHnUToyAU8Owis,87
|
|
11
11
|
phoenix/core/model.py,sha256=km_a--PBHOuA337ClRw9xqhOHhrUT6Rl9pz_zV0JYkQ,4843
|
|
@@ -18,23 +18,23 @@ phoenix/db/bulk_inserter.py,sha256=qgg8pt5k4VnHKOE0-KoReXVAfXRhLt-sMZihI-b4X9I,1
|
|
|
18
18
|
phoenix/db/engines.py,sha256=R3btYTSOSd6BwRA59EmhhojL0HCQ7NnzFIXQrPYS0iU,4812
|
|
19
19
|
phoenix/db/helpers.py,sha256=2zSc4n5IJfu-CaOFoBfqTB35M1nTFcAc8tqLsNtF2Jw,3488
|
|
20
20
|
phoenix/db/migrate.py,sha256=MuhtNWnR24riROvarvKfbRb4_D5xuQi6P760vBUKl1E,2270
|
|
21
|
-
phoenix/db/models.py,sha256=
|
|
21
|
+
phoenix/db/models.py,sha256=1fSwI9NjXcVv7PT40VEeKGGI13TWbqzrYfIemXV-DYY,20837
|
|
22
22
|
phoenix/db/insertion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
23
|
phoenix/db/insertion/constants.py,sha256=8wifm7X-1XvroZ__R2Gc96NsgLhTDn0zXl4lehlXtcA,70
|
|
24
24
|
phoenix/db/insertion/dataset.py,sha256=_vxy5e6W5jEuvO2fMKbbNCn9JvHkwI4LRKk_10eKFVg,7171
|
|
25
25
|
phoenix/db/insertion/document_annotation.py,sha256=qp8E63LzlthAScQg6opqln5Qg1d7UdtP3rkYL4riTgU,5983
|
|
26
26
|
phoenix/db/insertion/evaluation.py,sha256=SoI85N3MYUSeNgjKa5WzFw14OfNjNTjExv-2m3sxaR8,6371
|
|
27
27
|
phoenix/db/insertion/helpers.py,sha256=z_Wnckhdf-F7xadWgaAV5ScXnLft8EtaYJCuIkma2Vw,3486
|
|
28
|
-
phoenix/db/insertion/span.py,sha256
|
|
28
|
+
phoenix/db/insertion/span.py,sha256=-CXn2LlEv2u7xbz7m8X5jALQ-BUNNzTxPJEzSmjhTpA,5958
|
|
29
29
|
phoenix/db/insertion/span_annotation.py,sha256=eQK7fFjKjZGj25Qf_PTU9Q8DZiYJAw4lfcfdLKFsKe0,5259
|
|
30
30
|
phoenix/db/insertion/trace_annotation.py,sha256=36CwcxSvDo2r-_y_GlmMXGnlH4BKVaMu5BWM9w-9l7A,5324
|
|
31
31
|
phoenix/db/insertion/types.py,sha256=nQYYnpzcPxj2kdUoXfKE8ilOKlx1zpKLPc40OGuBlfk,8149
|
|
32
32
|
phoenix/db/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
33
|
phoenix/db/migrations/env.py,sha256=QbzB5zrRs6XQQmrYeUpuzeilcMlM-MsbaAgHHYcIHTI,3626
|
|
34
34
|
phoenix/db/migrations/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
|
|
35
|
-
phoenix/db/migrations/
|
|
36
|
-
phoenix/db/migrations/versions/
|
|
37
|
-
phoenix/db/migrations/versions/cf03bd6bae1d_init.py,sha256=
|
|
35
|
+
phoenix/db/migrations/versions/10460e46d750_datasets.py,sha256=eZAyz720DmpOd7RnuxDN2dVNXVuMrdlCA7eAOxyMtfs,8695
|
|
36
|
+
phoenix/db/migrations/versions/3be8647b87d8_add_token_columns_to_spans_table.py,sha256=x6oKFwn7Zmite4G0trDQPpMCn0I7jejuBcN3-ivEuDg,3938
|
|
37
|
+
phoenix/db/migrations/versions/cf03bd6bae1d_init.py,sha256=09cpofqje8zi4eQFfUn-i21x7VcsUYOfLKKUlrtKrGc,8662
|
|
38
38
|
phoenix/experiments/__init__.py,sha256=6JGwgUd7xCbGpuHqYZlsmErmYvVgv7N_j43bn3dUqsk,123
|
|
39
39
|
phoenix/experiments/functions.py,sha256=4XaOLE1Co9sW_yjM1sypQClmOLtt9kwoxmhIEJ3f_rk,32209
|
|
40
40
|
phoenix/experiments/tracing.py,sha256=wVpt8Ie9WNPoi1djJdcrkwCokHdTO0bicXViLg3O-1Y,2831
|
|
@@ -102,7 +102,7 @@ phoenix/server/api/dataloaders/span_dataset_examples.py,sha256=BtLZp11fyyeaWGGBP
|
|
|
102
102
|
phoenix/server/api/dataloaders/span_descendants.py,sha256=b7jGTn0Hi22gv2yskloLnf3BG3upS9z5hnKLMT9Sxac,2094
|
|
103
103
|
phoenix/server/api/dataloaders/span_evaluations.py,sha256=IfwXW23GQaWti8F49wSJocWf7Tklf2ZJ0F6aB4cSVHs,1248
|
|
104
104
|
phoenix/server/api/dataloaders/span_projects.py,sha256=LbQWiboCFqq4CHS18OzvRUwL9yORqP26fh5p7JbpFdg,1244
|
|
105
|
-
phoenix/server/api/dataloaders/token_counts.py,sha256=
|
|
105
|
+
phoenix/server/api/dataloaders/token_counts.py,sha256=6gDVely8BYiCBdmiq1ECO0lMChUYPIlsZbB34rmL1xM,4684
|
|
106
106
|
phoenix/server/api/dataloaders/trace_evaluations.py,sha256=vraPehNsausR4dbdvq-HudRVNARJUbep3T-Ud9jwWYY,1262
|
|
107
107
|
phoenix/server/api/dataloaders/trace_row_ids.py,sha256=RODX4NULlBzMxHMrsq0dp1ij6ZlLH4ZzQBnafGdxOvU,1100
|
|
108
108
|
phoenix/server/api/dataloaders/cache/__init__.py,sha256=SYoOM9n8FJaMdQarma5d1blu-jIg2GB8Shqg5ezSzZ8,106
|
|
@@ -133,7 +133,7 @@ phoenix/server/api/input_types/PatchDatasetExamplesInput.py,sha256=E86aBGXDBC83j
|
|
|
133
133
|
phoenix/server/api/input_types/PatchDatasetInput.py,sha256=OURtTVY8Z_oFEDtKwT1LCMaOK5D4QYo5TVQ6mDrex-g,328
|
|
134
134
|
phoenix/server/api/input_types/PerformanceMetricInput.py,sha256=fElsLTSEYYgGFGMYTEGcYid39tXUKFdV_JkdHavMcbA,591
|
|
135
135
|
phoenix/server/api/input_types/SpanAnnotationSort.py,sha256=T5pAGzmh4MiJp9JMAzNDByFVTczfw02FH4WFWwFezyI,361
|
|
136
|
-
phoenix/server/api/input_types/SpanSort.py,sha256=
|
|
136
|
+
phoenix/server/api/input_types/SpanSort.py,sha256=Dhvl8BIoV52yHoqntfOax_gUc15uH8ITI_00Ha7PvYc,5959
|
|
137
137
|
phoenix/server/api/input_types/TimeRange.py,sha256=yzx-gxj8mDeGLft1FzU_x1MVEgIG5Pt6-f8PUVDgipQ,522
|
|
138
138
|
phoenix/server/api/input_types/TraceAnnotationSort.py,sha256=BzwiUnMh2VsgQYnhDlbJ6ljHugqIS4YDUlYzvq_tl3o,365
|
|
139
139
|
phoenix/server/api/input_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -205,7 +205,7 @@ phoenix/server/api/types/Retrieval.py,sha256=OhMK2ncjoyp5h1yjKhjlKpoTbQrMHuxmgSF
|
|
|
205
205
|
phoenix/server/api/types/ScalarDriftMetricEnum.py,sha256=IUAcRPpgL41WdoIgK6cNk2Te38SspXGyEs-S1fY23_A,232
|
|
206
206
|
phoenix/server/api/types/Segments.py,sha256=m2yoegrxA1Tn7ZAy1rMjjD1isc752MaAXMoffkBlvrM,2921
|
|
207
207
|
phoenix/server/api/types/SortDir.py,sha256=OUpXhlCzCxPoXSDkJJygEs9Rw9pMymfaZUG5zPTrw4Y,152
|
|
208
|
-
phoenix/server/api/types/Span.py,sha256=
|
|
208
|
+
phoenix/server/api/types/Span.py,sha256=xzJoRuzFf1S64jDuPmGLjSFZ4oPyKUyfK1CtmtZ4LY0,14801
|
|
209
209
|
phoenix/server/api/types/SpanAnnotation.py,sha256=6b5G-b_OoRvDL2ayWk7MkbqarLK-F-pQMx21CpUuNGY,1168
|
|
210
210
|
phoenix/server/api/types/TimeSeries.py,sha256=wjzuxHFqCey0O7Ys25qiXyuqXK8an-osyNWUE8A_8G4,5227
|
|
211
211
|
phoenix/server/api/types/Trace.py,sha256=-nh3A-S_BlQK1VSSOTWqM85l-WwJsRHifxeDi0sFWZE,3246
|
|
@@ -227,13 +227,13 @@ phoenix/server/static/apple-touch-icon-76x76.png,sha256=CT_xT12I0u2i0WU8JzBZBuOQ
|
|
|
227
227
|
phoenix/server/static/apple-touch-icon.png,sha256=fOfpjqGpWYbJ0eAurKsyoZP1EAs6ZVooBJ_SGk2ZkDs,3801
|
|
228
228
|
phoenix/server/static/favicon.ico,sha256=bY0vvCKRftemZfPShwZtE93DiiQdaYaozkPGwNFr6H8,34494
|
|
229
229
|
phoenix/server/static/modernizr.js,sha256=mvK-XtkNqjOral-QvzoqsyOMECXIMu5BQwSVN_wcU9c,2564
|
|
230
|
-
phoenix/server/static/.vite/manifest.json,sha256=
|
|
231
|
-
phoenix/server/static/assets/components-
|
|
232
|
-
phoenix/server/static/assets/index-
|
|
233
|
-
phoenix/server/static/assets/pages-
|
|
230
|
+
phoenix/server/static/.vite/manifest.json,sha256=f_O0wfSXGRjeXvLiAE1oNla0ADk3X6PTSnCeHtd4xB8,1929
|
|
231
|
+
phoenix/server/static/assets/components-BSw2e1Zr.js,sha256=nvfZM0lYZkeOklzR8VLMikEgIOTpb2jNpF8b9IMMcps,185927
|
|
232
|
+
phoenix/server/static/assets/index-BYUFcdtx.js,sha256=bYcfXq3huGgFkCR0SX2680A1MbACjpdxd5MIbMcOIyY,7362
|
|
233
|
+
phoenix/server/static/assets/pages-p_fuED5k.js,sha256=MA3xlc64hC6bRMJRcXZ1v1sWZdsngaU8bcejbho402A,449363
|
|
234
234
|
phoenix/server/static/assets/vendor-BMWfu6zp.js,sha256=AAVTM5SjGUI_CmAWFUFmhpp5VDhvCD-MrEoh-pXXADY,1355423
|
|
235
235
|
phoenix/server/static/assets/vendor-DxkFTwjz.css,sha256=nZrkr0u6NNElFGvpWHk9GTHeGoibCXCli1bE7mXZGZg,1816
|
|
236
|
-
phoenix/server/static/assets/vendor-arizeai-
|
|
236
|
+
phoenix/server/static/assets/vendor-arizeai-CIETbKDq.js,sha256=JYd0o3cIY0av7lzU5LT5GDMMhmMPE3FbbGjtlhKBhLo,304008
|
|
237
237
|
phoenix/server/static/assets/vendor-codemirror-DO3VqEcD.js,sha256=M7t6xd6WpgKes25OOeGyxT1MU1dDrEKdmUBHgy5zslw,503031
|
|
238
238
|
phoenix/server/static/assets/vendor-recharts-BGN0SxgJ.js,sha256=L9LAYSjuf0GHh1_PQh9bF4l9euWCDVQcnQN1RgMDMBw,282859
|
|
239
239
|
phoenix/server/static/assets/vendor-three-DwGkEfCM.js,sha256=0D12ZgKzfKCTSdSTKJBFR2RZO_xxeMXrqDp0AszZqHY,620972
|
|
@@ -281,8 +281,8 @@ phoenix/utilities/logging.py,sha256=lDXd6EGaamBNcQxL4vP1au9-i_SXe0OraUDiJOcszSw,
|
|
|
281
281
|
phoenix/utilities/project.py,sha256=8IJuMM4yUMoooPi37sictGj8Etu9rGmq6RFtc9848cQ,436
|
|
282
282
|
phoenix/utilities/re.py,sha256=PDve_OLjRTM8yQQJHC8-n3HdIONi7aNils3ZKRZ5uBM,2045
|
|
283
283
|
phoenix/utilities/span_store.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
284
|
-
arize_phoenix-4.20.
|
|
285
|
-
arize_phoenix-4.20.
|
|
286
|
-
arize_phoenix-4.20.
|
|
287
|
-
arize_phoenix-4.20.
|
|
288
|
-
arize_phoenix-4.20.
|
|
284
|
+
arize_phoenix-4.20.2.dist-info/METADATA,sha256=DAffUocQNJm0BONMNSzCucpDNIILl9e2JIdARb3As3c,11902
|
|
285
|
+
arize_phoenix-4.20.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
286
|
+
arize_phoenix-4.20.2.dist-info/licenses/IP_NOTICE,sha256=JBqyyCYYxGDfzQ0TtsQgjts41IJoa-hiwDrBjCb9gHM,469
|
|
287
|
+
arize_phoenix-4.20.2.dist-info/licenses/LICENSE,sha256=HFkW9REuMOkvKRACuwLPT0hRydHb3zNg-fdFt94td18,3794
|
|
288
|
+
arize_phoenix-4.20.2.dist-info/RECORD,,
|
phoenix/db/insertion/span.py
CHANGED
|
@@ -71,6 +71,13 @@ async def insert_span(
|
|
|
71
71
|
cumulative_llm_token_count_completion = cast(
|
|
72
72
|
int, get_attribute_value(span.attributes, SpanAttributes.LLM_TOKEN_COUNT_COMPLETION) or 0
|
|
73
73
|
)
|
|
74
|
+
llm_token_count_prompt = cast(
|
|
75
|
+
Optional[int], get_attribute_value(span.attributes, SpanAttributes.LLM_TOKEN_COUNT_PROMPT)
|
|
76
|
+
)
|
|
77
|
+
llm_token_count_completion = cast(
|
|
78
|
+
Optional[int],
|
|
79
|
+
get_attribute_value(span.attributes, SpanAttributes.LLM_TOKEN_COUNT_COMPLETION),
|
|
80
|
+
)
|
|
74
81
|
if accumulation := (
|
|
75
82
|
await session.execute(
|
|
76
83
|
select(
|
|
@@ -100,6 +107,8 @@ async def insert_span(
|
|
|
100
107
|
cumulative_error_count=cumulative_error_count,
|
|
101
108
|
cumulative_llm_token_count_prompt=cumulative_llm_token_count_prompt,
|
|
102
109
|
cumulative_llm_token_count_completion=cumulative_llm_token_count_completion,
|
|
110
|
+
llm_token_count_prompt=llm_token_count_prompt,
|
|
111
|
+
llm_token_count_completion=llm_token_count_completion,
|
|
103
112
|
),
|
|
104
113
|
dialect=dialect,
|
|
105
114
|
table=models.Span,
|
|
@@ -6,11 +6,37 @@ Create Date: 2024-05-10 11:24:23.985834
|
|
|
6
6
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
from typing import Sequence, Union
|
|
9
|
+
from typing import Any, Sequence, Union
|
|
10
10
|
|
|
11
11
|
import sqlalchemy as sa
|
|
12
12
|
from alembic import op
|
|
13
|
-
from
|
|
13
|
+
from sqlalchemy import JSON
|
|
14
|
+
from sqlalchemy.dialects import postgresql
|
|
15
|
+
from sqlalchemy.ext.compiler import compiles
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class JSONB(JSON):
|
|
19
|
+
# See https://docs.sqlalchemy.org/en/20/core/custom_types.html
|
|
20
|
+
__visit_name__ = "JSONB"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@compiles(JSONB, "sqlite") # type: ignore
|
|
24
|
+
def _(*args: Any, **kwargs: Any) -> str:
|
|
25
|
+
# See https://docs.sqlalchemy.org/en/20/core/custom_types.html
|
|
26
|
+
return "JSONB"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
JSON_ = (
|
|
30
|
+
JSON()
|
|
31
|
+
.with_variant(
|
|
32
|
+
postgresql.JSONB(), # type: ignore
|
|
33
|
+
"postgresql",
|
|
34
|
+
)
|
|
35
|
+
.with_variant(
|
|
36
|
+
JSONB(),
|
|
37
|
+
"sqlite",
|
|
38
|
+
)
|
|
39
|
+
)
|
|
14
40
|
|
|
15
41
|
# revision identifiers, used by Alembic.
|
|
16
42
|
revision: str = "10460e46d750"
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""add token columns to spans table
|
|
2
|
+
|
|
3
|
+
Revision ID: 3be8647b87d8
|
|
4
|
+
Revises: 10460e46d750
|
|
5
|
+
Create Date: 2024-08-03 22:11:28.733133
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Any, Dict, List, Optional, Sequence, TypedDict, Union
|
|
10
|
+
|
|
11
|
+
import sqlalchemy as sa
|
|
12
|
+
from alembic import op
|
|
13
|
+
from openinference.semconv.trace import SpanAttributes
|
|
14
|
+
from sqlalchemy import (
|
|
15
|
+
JSON,
|
|
16
|
+
Dialect,
|
|
17
|
+
MetaData,
|
|
18
|
+
TypeDecorator,
|
|
19
|
+
update,
|
|
20
|
+
)
|
|
21
|
+
from sqlalchemy.dialects import postgresql
|
|
22
|
+
from sqlalchemy.ext.asyncio.engine import AsyncConnection
|
|
23
|
+
from sqlalchemy.ext.compiler import compiles
|
|
24
|
+
from sqlalchemy.orm import (
|
|
25
|
+
DeclarativeBase,
|
|
26
|
+
Mapped,
|
|
27
|
+
mapped_column,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class JSONB(JSON):
|
|
32
|
+
# See https://docs.sqlalchemy.org/en/20/core/custom_types.html
|
|
33
|
+
__visit_name__ = "JSONB"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@compiles(JSONB, "sqlite") # type: ignore
|
|
37
|
+
def _(*args: Any, **kwargs: Any) -> str:
|
|
38
|
+
# See https://docs.sqlalchemy.org/en/20/core/custom_types.html
|
|
39
|
+
return "JSONB"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
JSON_ = (
|
|
43
|
+
JSON()
|
|
44
|
+
.with_variant(
|
|
45
|
+
postgresql.JSONB(), # type: ignore
|
|
46
|
+
"postgresql",
|
|
47
|
+
)
|
|
48
|
+
.with_variant(
|
|
49
|
+
JSONB(),
|
|
50
|
+
"sqlite",
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class JsonDict(TypeDecorator[Dict[str, Any]]):
|
|
56
|
+
# See # See https://docs.sqlalchemy.org/en/20/core/custom_types.html
|
|
57
|
+
cache_ok = True
|
|
58
|
+
impl = JSON_
|
|
59
|
+
|
|
60
|
+
def process_bind_param(self, value: Optional[Dict[str, Any]], _: Dialect) -> Dict[str, Any]:
|
|
61
|
+
return value if isinstance(value, dict) else {}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class JsonList(TypeDecorator[List[Any]]):
|
|
65
|
+
# See # See https://docs.sqlalchemy.org/en/20/core/custom_types.html
|
|
66
|
+
cache_ok = True
|
|
67
|
+
impl = JSON_
|
|
68
|
+
|
|
69
|
+
def process_bind_param(self, value: Optional[List[Any]], _: Dialect) -> List[Any]:
|
|
70
|
+
return value if isinstance(value, list) else []
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ExperimentRunOutput(TypedDict, total=False):
|
|
74
|
+
task_output: Any
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class Base(DeclarativeBase):
|
|
78
|
+
# Enforce best practices for naming constraints
|
|
79
|
+
# https://alembic.sqlalchemy.org/en/latest/naming.html#integration-of-naming-conventions-into-operations-autogenerate
|
|
80
|
+
metadata = MetaData(
|
|
81
|
+
naming_convention={
|
|
82
|
+
"ix": "ix_%(table_name)s_%(column_0_N_name)s",
|
|
83
|
+
"uq": "uq_%(table_name)s_%(column_0_N_name)s",
|
|
84
|
+
"ck": "ck_%(table_name)s_`%(constraint_name)s`",
|
|
85
|
+
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
|
|
86
|
+
"pk": "pk_%(table_name)s",
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
type_annotation_map = {
|
|
90
|
+
Dict[str, Any]: JsonDict,
|
|
91
|
+
List[Dict[str, Any]]: JsonList,
|
|
92
|
+
ExperimentRunOutput: JsonDict,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class Span(Base):
|
|
97
|
+
__tablename__ = "spans"
|
|
98
|
+
id: Mapped[int] = mapped_column(primary_key=True)
|
|
99
|
+
attributes: Mapped[Dict[str, Any]]
|
|
100
|
+
llm_token_count_prompt: Mapped[Optional[int]]
|
|
101
|
+
llm_token_count_completion: Mapped[Optional[int]]
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# revision identifiers, used by Alembic.
|
|
105
|
+
revision: str = "3be8647b87d8"
|
|
106
|
+
down_revision: Union[str, None] = "10460e46d750"
|
|
107
|
+
branch_labels: Union[str, Sequence[str], None] = None
|
|
108
|
+
depends_on: Union[str, Sequence[str], None] = None
|
|
109
|
+
|
|
110
|
+
LLM_TOKEN_COUNT_PROMPT = SpanAttributes.LLM_TOKEN_COUNT_PROMPT.split(".")
|
|
111
|
+
LLM_TOKEN_COUNT_COMPLETION = SpanAttributes.LLM_TOKEN_COUNT_COMPLETION.split(".")
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
async def get_token_counts_from_attributes(connection: AsyncConnection) -> None:
|
|
115
|
+
"""
|
|
116
|
+
Gets token counts from attributes if present.
|
|
117
|
+
"""
|
|
118
|
+
await connection.execute(
|
|
119
|
+
update(Span).values(
|
|
120
|
+
llm_token_count_prompt=Span.attributes[LLM_TOKEN_COUNT_PROMPT].as_float(),
|
|
121
|
+
llm_token_count_completion=Span.attributes[LLM_TOKEN_COUNT_COMPLETION].as_float(),
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def upgrade() -> None:
|
|
127
|
+
op.add_column("spans", sa.Column("llm_token_count_prompt", sa.Integer, nullable=True))
|
|
128
|
+
op.add_column("spans", sa.Column("llm_token_count_completion", sa.Integer, nullable=True))
|
|
129
|
+
op.run_async(get_token_counts_from_attributes)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def downgrade() -> None:
|
|
133
|
+
op.drop_column("spans", "llm_token_count_completion")
|
|
134
|
+
op.drop_column("spans", "llm_token_count_prompt")
|
|
@@ -6,11 +6,37 @@ Create Date: 2024-04-03 19:41:48.871555
|
|
|
6
6
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
from typing import Sequence, Union
|
|
9
|
+
from typing import Any, Sequence, Union
|
|
10
10
|
|
|
11
11
|
import sqlalchemy as sa
|
|
12
12
|
from alembic import op
|
|
13
|
-
from
|
|
13
|
+
from sqlalchemy import JSON
|
|
14
|
+
from sqlalchemy.dialects import postgresql
|
|
15
|
+
from sqlalchemy.ext.compiler import compiles
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class JSONB(JSON):
|
|
19
|
+
# See https://docs.sqlalchemy.org/en/20/core/custom_types.html
|
|
20
|
+
__visit_name__ = "JSONB"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@compiles(JSONB, "sqlite") # type: ignore
|
|
24
|
+
def _(*args: Any, **kwargs: Any) -> str:
|
|
25
|
+
# See https://docs.sqlalchemy.org/en/20/core/custom_types.html
|
|
26
|
+
return "JSONB"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
JSON_ = (
|
|
30
|
+
JSON()
|
|
31
|
+
.with_variant(
|
|
32
|
+
postgresql.JSONB(), # type: ignore
|
|
33
|
+
"postgresql",
|
|
34
|
+
)
|
|
35
|
+
.with_variant(
|
|
36
|
+
JSONB(),
|
|
37
|
+
"sqlite",
|
|
38
|
+
)
|
|
39
|
+
)
|
|
14
40
|
|
|
15
41
|
# revision identifiers, used by Alembic.
|
|
16
42
|
revision: str = "cf03bd6bae1d"
|
phoenix/db/models.py
CHANGED
|
@@ -197,7 +197,7 @@ class Span(Base):
|
|
|
197
197
|
ForeignKey("traces.id", ondelete="CASCADE"),
|
|
198
198
|
index=True,
|
|
199
199
|
)
|
|
200
|
-
span_id: Mapped[str]
|
|
200
|
+
span_id: Mapped[str] = mapped_column(index=True)
|
|
201
201
|
parent_id: Mapped[Optional[str]] = mapped_column(index=True)
|
|
202
202
|
name: Mapped[str]
|
|
203
203
|
span_kind: Mapped[str]
|
|
@@ -214,6 +214,8 @@ class Span(Base):
|
|
|
214
214
|
cumulative_error_count: Mapped[int]
|
|
215
215
|
cumulative_llm_token_count_prompt: Mapped[int]
|
|
216
216
|
cumulative_llm_token_count_completion: Mapped[int]
|
|
217
|
+
llm_token_count_prompt: Mapped[Optional[int]]
|
|
218
|
+
llm_token_count_completion: Mapped[Optional[int]]
|
|
217
219
|
|
|
218
220
|
@hybrid_property
|
|
219
221
|
def latency_ms(self) -> float:
|
|
@@ -230,6 +232,12 @@ class Span(Base):
|
|
|
230
232
|
def cumulative_llm_token_count_total(self) -> int:
|
|
231
233
|
return self.cumulative_llm_token_count_prompt + self.cumulative_llm_token_count_completion
|
|
232
234
|
|
|
235
|
+
@hybrid_property
|
|
236
|
+
def llm_token_count_total(self) -> Optional[int]:
|
|
237
|
+
if self.llm_token_count_prompt is None and self.llm_token_count_completion is None:
|
|
238
|
+
return None
|
|
239
|
+
return (self.llm_token_count_prompt or 0) + (self.llm_token_count_completion or 0)
|
|
240
|
+
|
|
233
241
|
trace: Mapped["Trace"] = relationship("Trace", back_populates="spans")
|
|
234
242
|
document_annotations: Mapped[List["DocumentAnnotation"]] = relationship(back_populates="span")
|
|
235
243
|
dataset_examples: Mapped[List["DatasetExample"]] = relationship(back_populates="span")
|
|
@@ -10,7 +10,6 @@ from typing import (
|
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
from cachetools import LFUCache, TTLCache
|
|
13
|
-
from openinference.semconv.trace import SpanAttributes
|
|
14
13
|
from sqlalchemy import Select, func, select
|
|
15
14
|
from sqlalchemy.sql.functions import coalesce
|
|
16
15
|
from strawberry.dataloader import AbstractCache, DataLoader
|
|
@@ -107,8 +106,8 @@ def _get_stmt(
|
|
|
107
106
|
*params: Param,
|
|
108
107
|
) -> Select[Any]:
|
|
109
108
|
(start_time, end_time), filter_condition = segment
|
|
110
|
-
prompt = func.sum(models.Span.
|
|
111
|
-
completion = func.sum(models.Span.
|
|
109
|
+
prompt = func.sum(models.Span.llm_token_count_prompt)
|
|
110
|
+
completion = func.sum(models.Span.llm_token_count_completion)
|
|
112
111
|
total = coalesce(prompt, 0) + coalesce(completion, 0)
|
|
113
112
|
pid = models.Trace.project_rowid
|
|
114
113
|
stmt: Select[Any] = (
|
|
@@ -130,7 +129,3 @@ def _get_stmt(
|
|
|
130
129
|
stmt = sf(stmt)
|
|
131
130
|
stmt = stmt.where(pid.in_([rowid for rowid, _ in params]))
|
|
132
131
|
return stmt
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
_LLM_TOKEN_COUNT_PROMPT = SpanAttributes.LLM_TOKEN_COUNT_PROMPT.split(".")
|
|
136
|
-
_LLM_TOKEN_COUNT_COMPLETION = SpanAttributes.LLM_TOKEN_COUNT_COMPLETION.split(".")
|
|
@@ -3,7 +3,6 @@ from enum import Enum, auto
|
|
|
3
3
|
from typing import Any, Optional, Protocol
|
|
4
4
|
|
|
5
5
|
import strawberry
|
|
6
|
-
from openinference.semconv.trace import SpanAttributes
|
|
7
6
|
from sqlalchemy import and_, desc, nulls_last
|
|
8
7
|
from sqlalchemy.orm import InstrumentedAttribute
|
|
9
8
|
from sqlalchemy.sql.expression import Select
|
|
@@ -16,10 +15,6 @@ from phoenix.server.api.types.pagination import CursorSortColumnDataType
|
|
|
16
15
|
from phoenix.server.api.types.SortDir import SortDir
|
|
17
16
|
from phoenix.trace.schemas import SpanID
|
|
18
17
|
|
|
19
|
-
LLM_TOKEN_COUNT_PROMPT = SpanAttributes.LLM_TOKEN_COUNT_PROMPT.split(".")
|
|
20
|
-
LLM_TOKEN_COUNT_COMPLETION = SpanAttributes.LLM_TOKEN_COUNT_COMPLETION.split(".")
|
|
21
|
-
LLM_TOKEN_COUNT_TOTAL = SpanAttributes.LLM_TOKEN_COUNT_TOTAL.split(".")
|
|
22
|
-
|
|
23
18
|
|
|
24
19
|
@strawberry.enum
|
|
25
20
|
class SpanColumn(Enum):
|
|
@@ -47,11 +42,11 @@ class SpanColumn(Enum):
|
|
|
47
42
|
elif self is SpanColumn.latencyMs:
|
|
48
43
|
expr = models.Span.latency_ms
|
|
49
44
|
elif self is SpanColumn.tokenCountTotal:
|
|
50
|
-
expr = models.Span.
|
|
45
|
+
expr = models.Span.llm_token_count_total
|
|
51
46
|
elif self is SpanColumn.tokenCountPrompt:
|
|
52
|
-
expr = models.Span.
|
|
47
|
+
expr = models.Span.llm_token_count_prompt
|
|
53
48
|
elif self is SpanColumn.tokenCountCompletion:
|
|
54
|
-
expr = models.Span.
|
|
49
|
+
expr = models.Span.llm_token_count_completion
|
|
55
50
|
elif self is SpanColumn.cumulativeTokenCountTotal:
|
|
56
51
|
expr = (
|
|
57
52
|
models.Span.cumulative_llm_token_count_prompt
|
phoenix/server/api/types/Span.py
CHANGED
|
@@ -40,9 +40,6 @@ EMBEDDING_EMBEDDINGS = SpanAttributes.EMBEDDING_EMBEDDINGS
|
|
|
40
40
|
EMBEDDING_VECTOR = EmbeddingAttributes.EMBEDDING_VECTOR
|
|
41
41
|
INPUT_MIME_TYPE = SpanAttributes.INPUT_MIME_TYPE
|
|
42
42
|
INPUT_VALUE = SpanAttributes.INPUT_VALUE
|
|
43
|
-
LLM_TOKEN_COUNT_COMPLETION = SpanAttributes.LLM_TOKEN_COUNT_COMPLETION
|
|
44
|
-
LLM_TOKEN_COUNT_PROMPT = SpanAttributes.LLM_TOKEN_COUNT_PROMPT
|
|
45
|
-
LLM_TOKEN_COUNT_TOTAL = SpanAttributes.LLM_TOKEN_COUNT_TOTAL
|
|
46
43
|
LLM_PROMPT_TEMPLATE_VARIABLES = SpanAttributes.LLM_PROMPT_TEMPLATE_VARIABLES
|
|
47
44
|
LLM_INPUT_MESSAGES = SpanAttributes.LLM_INPUT_MESSAGES
|
|
48
45
|
LLM_OUTPUT_MESSAGES = SpanAttributes.LLM_OUTPUT_MESSAGES
|
|
@@ -308,18 +305,9 @@ def to_gql_span(span: models.Span) -> Span:
|
|
|
308
305
|
attributes=json.dumps(_hide_embedding_vectors(span.attributes), cls=_JSONEncoder),
|
|
309
306
|
metadata=_convert_metadata_to_string(get_attribute_value(span.attributes, METADATA)),
|
|
310
307
|
num_documents=num_documents,
|
|
311
|
-
token_count_total=
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
),
|
|
315
|
-
token_count_prompt=cast(
|
|
316
|
-
Optional[int],
|
|
317
|
-
get_attribute_value(span.attributes, LLM_TOKEN_COUNT_PROMPT),
|
|
318
|
-
),
|
|
319
|
-
token_count_completion=cast(
|
|
320
|
-
Optional[int],
|
|
321
|
-
get_attribute_value(span.attributes, LLM_TOKEN_COUNT_COMPLETION),
|
|
322
|
-
),
|
|
308
|
+
token_count_total=span.llm_token_count_total,
|
|
309
|
+
token_count_prompt=span.llm_token_count_prompt,
|
|
310
|
+
token_count_completion=span.llm_token_count_completion,
|
|
323
311
|
cumulative_token_count_total=span.cumulative_llm_token_count_prompt
|
|
324
312
|
+ span.cumulative_llm_token_count_completion,
|
|
325
313
|
cumulative_token_count_prompt=span.cumulative_llm_token_count_prompt,
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_components-
|
|
3
|
-
"file": "assets/components-
|
|
2
|
+
"_components-BSw2e1Zr.js": {
|
|
3
|
+
"file": "assets/components-BSw2e1Zr.js",
|
|
4
4
|
"name": "components",
|
|
5
5
|
"imports": [
|
|
6
6
|
"_vendor-BMWfu6zp.js",
|
|
7
|
-
"_vendor-arizeai-
|
|
8
|
-
"_pages-
|
|
7
|
+
"_vendor-arizeai-CIETbKDq.js",
|
|
8
|
+
"_pages-p_fuED5k.js",
|
|
9
9
|
"_vendor-three-DwGkEfCM.js",
|
|
10
10
|
"_vendor-codemirror-DO3VqEcD.js"
|
|
11
11
|
]
|
|
12
12
|
},
|
|
13
|
-
"_pages-
|
|
14
|
-
"file": "assets/pages-
|
|
13
|
+
"_pages-p_fuED5k.js": {
|
|
14
|
+
"file": "assets/pages-p_fuED5k.js",
|
|
15
15
|
"name": "pages",
|
|
16
16
|
"imports": [
|
|
17
17
|
"_vendor-BMWfu6zp.js",
|
|
18
|
-
"_components-
|
|
19
|
-
"_vendor-arizeai-
|
|
18
|
+
"_components-BSw2e1Zr.js",
|
|
19
|
+
"_vendor-arizeai-CIETbKDq.js",
|
|
20
20
|
"_vendor-recharts-BGN0SxgJ.js",
|
|
21
21
|
"_vendor-codemirror-DO3VqEcD.js"
|
|
22
22
|
]
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"assets/vendor-DxkFTwjz.css"
|
|
36
36
|
]
|
|
37
37
|
},
|
|
38
|
-
"_vendor-arizeai-
|
|
39
|
-
"file": "assets/vendor-arizeai-
|
|
38
|
+
"_vendor-arizeai-CIETbKDq.js": {
|
|
39
|
+
"file": "assets/vendor-arizeai-CIETbKDq.js",
|
|
40
40
|
"name": "vendor-arizeai",
|
|
41
41
|
"imports": [
|
|
42
42
|
"_vendor-BMWfu6zp.js"
|
|
@@ -61,15 +61,15 @@
|
|
|
61
61
|
"name": "vendor-three"
|
|
62
62
|
},
|
|
63
63
|
"index.tsx": {
|
|
64
|
-
"file": "assets/index-
|
|
64
|
+
"file": "assets/index-BYUFcdtx.js",
|
|
65
65
|
"name": "index",
|
|
66
66
|
"src": "index.tsx",
|
|
67
67
|
"isEntry": true,
|
|
68
68
|
"imports": [
|
|
69
69
|
"_vendor-BMWfu6zp.js",
|
|
70
|
-
"_vendor-arizeai-
|
|
71
|
-
"_components-
|
|
72
|
-
"_pages-
|
|
70
|
+
"_vendor-arizeai-CIETbKDq.js",
|
|
71
|
+
"_components-BSw2e1Zr.js",
|
|
72
|
+
"_pages-p_fuED5k.js",
|
|
73
73
|
"_vendor-three-DwGkEfCM.js",
|
|
74
74
|
"_vendor-codemirror-DO3VqEcD.js",
|
|
75
75
|
"_vendor-recharts-BGN0SxgJ.js"
|