arize-phoenix 11.37.0__py3-none-any.whl → 12.0.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 (75) hide show
  1. {arize_phoenix-11.37.0.dist-info → arize_phoenix-12.0.0.dist-info}/METADATA +3 -3
  2. {arize_phoenix-11.37.0.dist-info → arize_phoenix-12.0.0.dist-info}/RECORD +74 -53
  3. phoenix/config.py +1 -11
  4. phoenix/db/bulk_inserter.py +8 -0
  5. phoenix/db/facilitator.py +1 -1
  6. phoenix/db/helpers.py +202 -33
  7. phoenix/db/insertion/dataset.py +7 -0
  8. phoenix/db/insertion/helpers.py +2 -2
  9. phoenix/db/insertion/session_annotation.py +176 -0
  10. phoenix/db/insertion/types.py +30 -0
  11. phoenix/db/migrations/versions/01a8342c9cdf_add_user_id_on_datasets.py +40 -0
  12. phoenix/db/migrations/versions/0df286449799_add_session_annotations_table.py +105 -0
  13. phoenix/db/migrations/versions/272b66ff50f8_drop_single_indices.py +119 -0
  14. phoenix/db/migrations/versions/58228d933c91_dataset_labels.py +67 -0
  15. phoenix/db/migrations/versions/699f655af132_experiment_tags.py +57 -0
  16. phoenix/db/migrations/versions/735d3d93c33e_add_composite_indices.py +41 -0
  17. phoenix/db/migrations/versions/ab513d89518b_add_user_id_on_dataset_versions.py +40 -0
  18. phoenix/db/migrations/versions/d0690a79ea51_users_on_experiments.py +40 -0
  19. phoenix/db/migrations/versions/deb2c81c0bb2_dataset_splits.py +139 -0
  20. phoenix/db/migrations/versions/e76cbd66ffc3_add_experiments_dataset_examples.py +87 -0
  21. phoenix/db/models.py +285 -46
  22. phoenix/server/api/context.py +13 -2
  23. phoenix/server/api/dataloaders/__init__.py +6 -2
  24. phoenix/server/api/dataloaders/dataset_example_splits.py +40 -0
  25. phoenix/server/api/dataloaders/session_annotations_by_session.py +29 -0
  26. phoenix/server/api/dataloaders/table_fields.py +2 -2
  27. phoenix/server/api/dataloaders/trace_annotations_by_trace.py +27 -0
  28. phoenix/server/api/helpers/playground_clients.py +65 -35
  29. phoenix/server/api/helpers/playground_spans.py +2 -1
  30. phoenix/server/api/helpers/playground_users.py +26 -0
  31. phoenix/server/api/input_types/{SpanAnnotationFilter.py → AnnotationFilter.py} +22 -14
  32. phoenix/server/api/input_types/ChatCompletionInput.py +2 -0
  33. phoenix/server/api/input_types/CreateProjectSessionAnnotationInput.py +37 -0
  34. phoenix/server/api/input_types/UpdateAnnotationInput.py +34 -0
  35. phoenix/server/api/mutations/__init__.py +6 -0
  36. phoenix/server/api/mutations/chat_mutations.py +24 -9
  37. phoenix/server/api/mutations/dataset_mutations.py +5 -0
  38. phoenix/server/api/mutations/dataset_split_mutations.py +387 -0
  39. phoenix/server/api/mutations/project_session_annotations_mutations.py +161 -0
  40. phoenix/server/api/queries.py +32 -0
  41. phoenix/server/api/routers/v1/__init__.py +2 -0
  42. phoenix/server/api/routers/v1/annotations.py +320 -0
  43. phoenix/server/api/routers/v1/datasets.py +5 -0
  44. phoenix/server/api/routers/v1/experiments.py +10 -3
  45. phoenix/server/api/routers/v1/sessions.py +111 -0
  46. phoenix/server/api/routers/v1/traces.py +1 -2
  47. phoenix/server/api/routers/v1/users.py +7 -0
  48. phoenix/server/api/subscriptions.py +25 -7
  49. phoenix/server/api/types/ChatCompletionSubscriptionPayload.py +1 -0
  50. phoenix/server/api/types/DatasetExample.py +11 -0
  51. phoenix/server/api/types/DatasetSplit.py +32 -0
  52. phoenix/server/api/types/Experiment.py +0 -4
  53. phoenix/server/api/types/Project.py +16 -0
  54. phoenix/server/api/types/ProjectSession.py +88 -3
  55. phoenix/server/api/types/ProjectSessionAnnotation.py +68 -0
  56. phoenix/server/api/types/Span.py +5 -5
  57. phoenix/server/api/types/Trace.py +61 -0
  58. phoenix/server/app.py +6 -2
  59. phoenix/server/cost_tracking/model_cost_manifest.json +132 -2
  60. phoenix/server/dml_event.py +13 -0
  61. phoenix/server/static/.vite/manifest.json +39 -39
  62. phoenix/server/static/assets/{components-CFzdBkk_.js → components-Dl9SUw1U.js} +371 -327
  63. phoenix/server/static/assets/{index-DayUA9lQ.js → index-CqQS0dTo.js} +2 -2
  64. phoenix/server/static/assets/{pages-CvUhOO9h.js → pages-DKSjVA_E.js} +771 -518
  65. phoenix/server/static/assets/{vendor-BdjZxMii.js → vendor-CtbHQYl8.js} +1 -1
  66. phoenix/server/static/assets/{vendor-arizeai-CHYlS8jV.js → vendor-arizeai-D-lWOwIS.js} +1 -1
  67. phoenix/server/static/assets/{vendor-codemirror-Di6t4HnH.js → vendor-codemirror-BRBpy3_z.js} +3 -3
  68. phoenix/server/static/assets/{vendor-recharts-C9wCDYj3.js → vendor-recharts--KdSwB3m.js} +1 -1
  69. phoenix/server/static/assets/{vendor-shiki-MNnmOotP.js → vendor-shiki-CvRzZnIo.js} +1 -1
  70. phoenix/version.py +1 -1
  71. phoenix/server/api/dataloaders/experiment_repetition_counts.py +0 -39
  72. {arize_phoenix-11.37.0.dist-info → arize_phoenix-12.0.0.dist-info}/WHEEL +0 -0
  73. {arize_phoenix-11.37.0.dist-info → arize_phoenix-12.0.0.dist-info}/entry_points.txt +0 -0
  74. {arize_phoenix-11.37.0.dist-info → arize_phoenix-12.0.0.dist-info}/licenses/IP_NOTICE +0 -0
  75. {arize_phoenix-11.37.0.dist-info → arize_phoenix-12.0.0.dist-info}/licenses/LICENSE +0 -0
phoenix/db/models.py CHANGED
@@ -20,6 +20,7 @@ from sqlalchemy import (
20
20
  Integer,
21
21
  MetaData,
22
22
  Null,
23
+ PrimaryKeyConstraint,
23
24
  String,
24
25
  TypeDecorator,
25
26
  UniqueConstraint,
@@ -154,7 +155,7 @@ def render_values_w_union(
154
155
  return compiler.process(subquery, from_linter=from_linter, **kw)
155
156
 
156
157
 
157
- UserRoleName: TypeAlias = Literal["SYSTEM", "ADMIN", "MEMBER"]
158
+ UserRoleName: TypeAlias = Literal["SYSTEM", "ADMIN", "MEMBER", "VIEWER"]
158
159
  AuthMethod: TypeAlias = Literal["LOCAL", "OAUTH2"]
159
160
 
160
161
 
@@ -447,7 +448,6 @@ class ExperimentRunOutput(TypedDict, total=False):
447
448
 
448
449
 
449
450
  class Base(DeclarativeBase):
450
- id: Mapped[int] = mapped_column(primary_key=True)
451
451
  # Enforce best practices for naming constraints
452
452
  # https://alembic.sqlalchemy.org/en/latest/naming.html#integration-of-naming-conventions-into-operations-autogenerate
453
453
  metadata = MetaData(
@@ -467,7 +467,12 @@ class Base(DeclarativeBase):
467
467
  }
468
468
 
469
469
 
470
- class ProjectTraceRetentionPolicy(Base):
470
+ class HasId(Base):
471
+ __abstract__ = True
472
+ id: Mapped[int] = mapped_column(primary_key=True)
473
+
474
+
475
+ class ProjectTraceRetentionPolicy(HasId):
471
476
  __tablename__ = "project_trace_retention_policies"
472
477
  name: Mapped[str] = mapped_column(String, nullable=False)
473
478
  cron_expression: Mapped[TraceRetentionCronExpression] = mapped_column(
@@ -479,7 +484,7 @@ class ProjectTraceRetentionPolicy(Base):
479
484
  )
480
485
 
481
486
 
482
- class Project(Base):
487
+ class Project(HasId):
483
488
  __tablename__ = "projects"
484
489
  name: Mapped[str]
485
490
  description: Mapped[Optional[str]]
@@ -519,7 +524,7 @@ class Project(Base):
519
524
  )
520
525
 
521
526
 
522
- class ProjectSession(Base):
527
+ class ProjectSession(HasId):
523
528
  __tablename__ = "project_sessions"
524
529
  session_id: Mapped[str] = mapped_column(String, nullable=False, unique=True)
525
530
  project_id: Mapped[int] = mapped_column(
@@ -536,7 +541,7 @@ class ProjectSession(Base):
536
541
  )
537
542
 
538
543
 
539
- class Trace(Base):
544
+ class Trace(HasId):
540
545
  __tablename__ = "traces"
541
546
  project_rowid: Mapped[int] = mapped_column(
542
547
  ForeignKey("projects.id", ondelete="CASCADE"),
@@ -591,13 +596,13 @@ class Trace(Base):
591
596
  )
592
597
 
593
598
 
594
- class Span(Base):
599
+ class Span(HasId):
595
600
  __tablename__ = "spans"
596
601
  trace_rowid: Mapped[int] = mapped_column(
597
602
  ForeignKey("traces.id", ondelete="CASCADE"),
598
603
  index=True,
599
604
  )
600
- span_id: Mapped[str] = mapped_column(index=True)
605
+ span_id: Mapped[str]
601
606
  parent_id: Mapped[Optional[str]] = mapped_column(index=True)
602
607
  name: Mapped[str]
603
608
  span_kind: Mapped[str]
@@ -894,15 +899,15 @@ async def init_models(engine: AsyncEngine) -> None:
894
899
  )
895
900
 
896
901
 
897
- class SpanAnnotation(Base):
902
+ class SpanAnnotation(HasId):
898
903
  __tablename__ = "span_annotations"
899
904
  span_rowid: Mapped[int] = mapped_column(
900
905
  ForeignKey("spans.id", ondelete="CASCADE"),
901
906
  index=True,
902
907
  )
903
908
  name: Mapped[str]
904
- label: Mapped[Optional[str]] = mapped_column(String, index=True)
905
- score: Mapped[Optional[float]] = mapped_column(Float, index=True)
909
+ label: Mapped[Optional[str]]
910
+ score: Mapped[Optional[float]]
906
911
  explanation: Mapped[Optional[str]]
907
912
  metadata_: Mapped[dict[str, Any]] = mapped_column("metadata")
908
913
  annotator_kind: Mapped[Literal["LLM", "CODE", "HUMAN"]] = mapped_column(
@@ -934,15 +939,15 @@ class SpanAnnotation(Base):
934
939
  )
935
940
 
936
941
 
937
- class TraceAnnotation(Base):
942
+ class TraceAnnotation(HasId):
938
943
  __tablename__ = "trace_annotations"
939
944
  trace_rowid: Mapped[int] = mapped_column(
940
945
  ForeignKey("traces.id", ondelete="CASCADE"),
941
946
  index=True,
942
947
  )
943
948
  name: Mapped[str]
944
- label: Mapped[Optional[str]] = mapped_column(String, index=True)
945
- score: Mapped[Optional[float]] = mapped_column(Float, index=True)
949
+ label: Mapped[Optional[str]]
950
+ score: Mapped[Optional[float]]
946
951
  explanation: Mapped[Optional[str]]
947
952
  metadata_: Mapped[dict[str, Any]] = mapped_column("metadata")
948
953
  annotator_kind: Mapped[Literal["LLM", "CODE", "HUMAN"]] = mapped_column(
@@ -971,7 +976,7 @@ class TraceAnnotation(Base):
971
976
  )
972
977
 
973
978
 
974
- class DocumentAnnotation(Base):
979
+ class DocumentAnnotation(HasId):
975
980
  __tablename__ = "document_annotations"
976
981
  span_rowid: Mapped[int] = mapped_column(
977
982
  ForeignKey("spans.id", ondelete="CASCADE"),
@@ -979,8 +984,8 @@ class DocumentAnnotation(Base):
979
984
  )
980
985
  document_position: Mapped[int]
981
986
  name: Mapped[str]
982
- label: Mapped[Optional[str]] = mapped_column(String, index=True)
983
- score: Mapped[Optional[float]] = mapped_column(Float, index=True)
987
+ label: Mapped[Optional[str]]
988
+ score: Mapped[Optional[float]]
984
989
  explanation: Mapped[Optional[str]]
985
990
  metadata_: Mapped[dict[str, Any]] = mapped_column("metadata")
986
991
  annotator_kind: Mapped[Literal["LLM", "CODE", "HUMAN"]] = mapped_column(
@@ -1012,7 +1017,44 @@ class DocumentAnnotation(Base):
1012
1017
  )
1013
1018
 
1014
1019
 
1015
- class Dataset(Base):
1020
+ class ProjectSessionAnnotation(HasId):
1021
+ __tablename__ = "project_session_annotations"
1022
+ project_session_id: Mapped[int] = mapped_column(
1023
+ ForeignKey("project_sessions.id", ondelete="CASCADE"),
1024
+ index=True,
1025
+ )
1026
+ name: Mapped[str]
1027
+ label: Mapped[Optional[str]]
1028
+ score: Mapped[Optional[float]]
1029
+ explanation: Mapped[Optional[str]]
1030
+ metadata_: Mapped[dict[str, Any]] = mapped_column("metadata")
1031
+ annotator_kind: Mapped[Literal["LLM", "CODE", "HUMAN"]] = mapped_column(
1032
+ CheckConstraint("annotator_kind IN ('LLM', 'CODE', 'HUMAN')", name="valid_annotator_kind"),
1033
+ )
1034
+ created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
1035
+ updated_at: Mapped[datetime] = mapped_column(
1036
+ UtcTimeStamp, server_default=func.now(), onupdate=func.now()
1037
+ )
1038
+ identifier: Mapped[str] = mapped_column(
1039
+ String,
1040
+ server_default="",
1041
+ nullable=False,
1042
+ )
1043
+ source: Mapped[Literal["API", "APP"]] = mapped_column(
1044
+ CheckConstraint("source IN ('API', 'APP')", name="valid_source"),
1045
+ )
1046
+ user_id: Mapped[Optional[int]] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"))
1047
+
1048
+ __table_args__ = (
1049
+ UniqueConstraint(
1050
+ "name",
1051
+ "project_session_id",
1052
+ "identifier",
1053
+ ),
1054
+ )
1055
+
1056
+
1057
+ class Dataset(HasId):
1016
1058
  __tablename__ = "datasets"
1017
1059
  name: Mapped[str] = mapped_column(unique=True)
1018
1060
  description: Mapped[Optional[str]]
@@ -1021,6 +1063,14 @@ class Dataset(Base):
1021
1063
  updated_at: Mapped[datetime] = mapped_column(
1022
1064
  UtcTimeStamp, server_default=func.now(), onupdate=func.now()
1023
1065
  )
1066
+ user_id: Mapped[Optional[int]] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"))
1067
+ user: Mapped[Optional["User"]] = relationship("User")
1068
+ experiment_tags: Mapped[list["ExperimentTag"]] = relationship(
1069
+ "ExperimentTag", back_populates="dataset"
1070
+ )
1071
+ datasets_dataset_labels: Mapped[list["DatasetsDatasetLabel"]] = relationship(
1072
+ "DatasetsDatasetLabel", back_populates="dataset"
1073
+ )
1024
1074
 
1025
1075
  @hybrid_property
1026
1076
  def example_count(self) -> Optional[int]:
@@ -1071,7 +1121,45 @@ class Dataset(Base):
1071
1121
  )
1072
1122
 
1073
1123
 
1074
- class DatasetVersion(Base):
1124
+ class DatasetLabel(HasId):
1125
+ __tablename__ = "dataset_labels"
1126
+ name: Mapped[str] = mapped_column(unique=True)
1127
+ description: Mapped[Optional[str]]
1128
+ color: Mapped[str] = mapped_column(String, nullable=False)
1129
+ datasets_dataset_labels: Mapped[list["DatasetsDatasetLabel"]] = relationship(
1130
+ "DatasetsDatasetLabel", back_populates="dataset_label"
1131
+ )
1132
+ user_id: Mapped[Optional[int]] = mapped_column(
1133
+ ForeignKey("users.id", ondelete="SET NULL"),
1134
+ nullable=True,
1135
+ )
1136
+ user: Mapped[Optional["User"]] = relationship("User")
1137
+
1138
+
1139
+ class DatasetsDatasetLabel(Base):
1140
+ __tablename__ = "datasets_dataset_labels"
1141
+ dataset_id: Mapped[int] = mapped_column(
1142
+ ForeignKey("datasets.id", ondelete="CASCADE"),
1143
+ )
1144
+ dataset_label_id: Mapped[int] = mapped_column(
1145
+ ForeignKey("dataset_labels.id", ondelete="CASCADE"),
1146
+ # index on the second element of the composite primary key
1147
+ index=True,
1148
+ )
1149
+ dataset: Mapped["Dataset"] = relationship("Dataset", back_populates="datasets_dataset_labels")
1150
+ dataset_label: Mapped["DatasetLabel"] = relationship(
1151
+ "DatasetLabel", back_populates="datasets_dataset_labels"
1152
+ )
1153
+
1154
+ __table_args__ = (
1155
+ PrimaryKeyConstraint(
1156
+ "dataset_id",
1157
+ "dataset_label_id",
1158
+ ),
1159
+ )
1160
+
1161
+
1162
+ class DatasetVersion(HasId):
1075
1163
  __tablename__ = "dataset_versions"
1076
1164
  dataset_id: Mapped[int] = mapped_column(
1077
1165
  ForeignKey("datasets.id", ondelete="CASCADE"),
@@ -1080,9 +1168,11 @@ class DatasetVersion(Base):
1080
1168
  description: Mapped[Optional[str]]
1081
1169
  metadata_: Mapped[dict[str, Any]] = mapped_column("metadata")
1082
1170
  created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
1171
+ user_id: Mapped[Optional[int]] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"))
1172
+ user: Mapped[Optional["User"]] = relationship("User")
1083
1173
 
1084
1174
 
1085
- class DatasetExample(Base):
1175
+ class DatasetExample(HasId):
1086
1176
  __tablename__ = "dataset_examples"
1087
1177
  dataset_id: Mapped[int] = mapped_column(
1088
1178
  ForeignKey("datasets.id", ondelete="CASCADE"),
@@ -1096,13 +1186,20 @@ class DatasetExample(Base):
1096
1186
  created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
1097
1187
 
1098
1188
  span: Mapped[Optional[Span]] = relationship(back_populates="dataset_examples")
1189
+ dataset_splits_dataset_examples: Mapped[list["DatasetSplitDatasetExample"]] = relationship(
1190
+ "DatasetSplitDatasetExample",
1191
+ back_populates="dataset_example",
1192
+ )
1193
+ experiment_dataset_examples: Mapped[list["ExperimentDatasetExample"]] = relationship(
1194
+ "ExperimentDatasetExample",
1195
+ back_populates="dataset_example",
1196
+ )
1099
1197
 
1100
1198
 
1101
- class DatasetExampleRevision(Base):
1199
+ class DatasetExampleRevision(HasId):
1102
1200
  __tablename__ = "dataset_example_revisions"
1103
1201
  dataset_example_id: Mapped[int] = mapped_column(
1104
1202
  ForeignKey("dataset_examples.id", ondelete="CASCADE"),
1105
- index=True,
1106
1203
  )
1107
1204
  dataset_version_id: Mapped[int] = mapped_column(
1108
1205
  ForeignKey("dataset_versions.id", ondelete="CASCADE"),
@@ -1118,6 +1215,11 @@ class DatasetExampleRevision(Base):
1118
1215
  )
1119
1216
  created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
1120
1217
 
1218
+ experiment_dataset_examples: Mapped[list["ExperimentDatasetExample"]] = relationship(
1219
+ "ExperimentDatasetExample",
1220
+ back_populates="dataset_example_revision",
1221
+ )
1222
+
1121
1223
  __table_args__ = (
1122
1224
  UniqueConstraint(
1123
1225
  "dataset_example_id",
@@ -1126,7 +1228,56 @@ class DatasetExampleRevision(Base):
1126
1228
  )
1127
1229
 
1128
1230
 
1129
- class Experiment(Base):
1231
+ class DatasetSplit(HasId):
1232
+ __tablename__ = "dataset_splits"
1233
+
1234
+ user_id: Mapped[Optional[int]] = mapped_column(
1235
+ ForeignKey("users.id", ondelete="SET NULL"),
1236
+ nullable=True,
1237
+ index=True,
1238
+ )
1239
+ name: Mapped[str] = mapped_column(String, nullable=False, unique=True)
1240
+ description: Mapped[Optional[str]]
1241
+ color: Mapped[str] = mapped_column(String, nullable=False)
1242
+ metadata_: Mapped[dict[str, Any]] = mapped_column("metadata")
1243
+ created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
1244
+ updated_at: Mapped[datetime] = mapped_column(
1245
+ UtcTimeStamp, server_default=func.now(), onupdate=func.now()
1246
+ )
1247
+ dataset_splits_dataset_examples: Mapped[list["DatasetSplitDatasetExample"]] = relationship(
1248
+ "DatasetSplitDatasetExample",
1249
+ back_populates="dataset_split",
1250
+ )
1251
+ experiment_dataset_splits: Mapped[list["ExperimentDatasetSplit"]] = relationship(
1252
+ "ExperimentDatasetSplit",
1253
+ back_populates="dataset_split",
1254
+ )
1255
+
1256
+
1257
+ class DatasetSplitDatasetExample(Base):
1258
+ __tablename__ = "dataset_splits_dataset_examples"
1259
+ dataset_split_id: Mapped[int] = mapped_column(
1260
+ ForeignKey("dataset_splits.id", ondelete="CASCADE"),
1261
+ )
1262
+ dataset_example_id: Mapped[int] = mapped_column(
1263
+ ForeignKey("dataset_examples.id", ondelete="CASCADE"),
1264
+ index=True,
1265
+ )
1266
+ dataset_split: Mapped["DatasetSplit"] = relationship(
1267
+ "DatasetSplit", back_populates="dataset_splits_dataset_examples"
1268
+ )
1269
+ dataset_example: Mapped["DatasetExample"] = relationship(
1270
+ "DatasetExample", back_populates="dataset_splits_dataset_examples"
1271
+ )
1272
+ __table_args__ = (
1273
+ PrimaryKeyConstraint(
1274
+ "dataset_split_id",
1275
+ "dataset_example_id",
1276
+ ),
1277
+ )
1278
+
1279
+
1280
+ class Experiment(HasId):
1130
1281
  __tablename__ = "experiments"
1131
1282
  dataset_id: Mapped[int] = mapped_column(
1132
1283
  ForeignKey("datasets.id", ondelete="CASCADE"),
@@ -1141,18 +1292,83 @@ class Experiment(Base):
1141
1292
  repetitions: Mapped[int]
1142
1293
  metadata_: Mapped[dict[str, Any]] = mapped_column("metadata")
1143
1294
  project_name: Mapped[Optional[str]] = mapped_column(index=True)
1295
+ user_id: Mapped[Optional[int]] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"))
1144
1296
  created_at: Mapped[datetime] = mapped_column(UtcTimeStamp, server_default=func.now())
1145
1297
  updated_at: Mapped[datetime] = mapped_column(
1146
1298
  UtcTimeStamp, server_default=func.now(), onupdate=func.now()
1147
1299
  )
1300
+ user: Mapped[Optional["User"]] = relationship("User")
1301
+ experiment_dataset_splits: Mapped[list["ExperimentDatasetSplit"]] = relationship(
1302
+ "ExperimentDatasetSplit",
1303
+ back_populates="experiment",
1304
+ )
1305
+ experiment_dataset_examples: Mapped[list["ExperimentDatasetExample"]] = relationship(
1306
+ "ExperimentDatasetExample",
1307
+ back_populates="experiment",
1308
+ )
1309
+ experiment_tags: Mapped[list["ExperimentTag"]] = relationship(
1310
+ "ExperimentTag", back_populates="experiment"
1311
+ )
1148
1312
 
1149
1313
 
1150
- class ExperimentRun(Base):
1151
- __tablename__ = "experiment_runs"
1314
+ class ExperimentDatasetSplit(Base):
1315
+ __tablename__ = "experiments_dataset_splits"
1152
1316
  experiment_id: Mapped[int] = mapped_column(
1153
1317
  ForeignKey("experiments.id", ondelete="CASCADE"),
1318
+ )
1319
+ dataset_split_id: Mapped[int] = mapped_column(
1320
+ ForeignKey("dataset_splits.id", ondelete="CASCADE"),
1154
1321
  index=True,
1155
1322
  )
1323
+ experiment: Mapped["Experiment"] = relationship(
1324
+ "Experiment", back_populates="experiment_dataset_splits"
1325
+ )
1326
+ dataset_split: Mapped["DatasetSplit"] = relationship(
1327
+ "DatasetSplit", back_populates="experiment_dataset_splits"
1328
+ )
1329
+ __table_args__ = (
1330
+ PrimaryKeyConstraint(
1331
+ "experiment_id",
1332
+ "dataset_split_id",
1333
+ ),
1334
+ )
1335
+
1336
+
1337
+ class ExperimentDatasetExample(Base):
1338
+ __tablename__ = "experiments_dataset_examples"
1339
+ experiment_id: Mapped[int] = mapped_column(
1340
+ ForeignKey("experiments.id", ondelete="CASCADE"),
1341
+ )
1342
+ dataset_example_id: Mapped[int] = mapped_column(
1343
+ ForeignKey("dataset_examples.id", ondelete="CASCADE"),
1344
+ index=True,
1345
+ )
1346
+ dataset_example_revision_id: Mapped[int] = mapped_column(
1347
+ ForeignKey("dataset_example_revisions.id", ondelete="CASCADE"),
1348
+ index=True,
1349
+ )
1350
+ experiment: Mapped["Experiment"] = relationship(
1351
+ "Experiment", back_populates="experiment_dataset_examples"
1352
+ )
1353
+ dataset_example: Mapped["DatasetExample"] = relationship(
1354
+ "DatasetExample", back_populates="experiment_dataset_examples"
1355
+ )
1356
+ dataset_example_revision: Mapped["DatasetExampleRevision"] = relationship(
1357
+ "DatasetExampleRevision", back_populates="experiment_dataset_examples"
1358
+ )
1359
+ __table_args__ = (
1360
+ PrimaryKeyConstraint(
1361
+ "experiment_id",
1362
+ "dataset_example_id",
1363
+ ),
1364
+ )
1365
+
1366
+
1367
+ class ExperimentRun(HasId):
1368
+ __tablename__ = "experiment_runs"
1369
+ experiment_id: Mapped[int] = mapped_column(
1370
+ ForeignKey("experiments.id", ondelete="CASCADE"),
1371
+ )
1156
1372
  dataset_example_id: Mapped[int] = mapped_column(
1157
1373
  ForeignKey("dataset_examples.id", ondelete="CASCADE"),
1158
1374
  index=True,
@@ -1192,11 +1408,10 @@ class ExperimentRun(Base):
1192
1408
  )
1193
1409
 
1194
1410
 
1195
- class ExperimentRunAnnotation(Base):
1411
+ class ExperimentRunAnnotation(HasId):
1196
1412
  __tablename__ = "experiment_run_annotations"
1197
1413
  experiment_run_id: Mapped[int] = mapped_column(
1198
1414
  ForeignKey("experiment_runs.id", ondelete="CASCADE"),
1199
- index=True,
1200
1415
  )
1201
1416
  name: Mapped[str]
1202
1417
  annotator_kind: Mapped[str] = mapped_column(
@@ -1223,13 +1438,36 @@ class ExperimentRunAnnotation(Base):
1223
1438
  )
1224
1439
 
1225
1440
 
1226
- class UserRole(Base):
1441
+ class ExperimentTag(HasId):
1442
+ __tablename__ = "experiment_tags"
1443
+ experiment_id: Mapped[int] = mapped_column(
1444
+ ForeignKey("experiments.id", ondelete="CASCADE"),
1445
+ index=True,
1446
+ )
1447
+ dataset_id: Mapped[int] = mapped_column(
1448
+ ForeignKey("datasets.id", ondelete="CASCADE"),
1449
+ )
1450
+ user_id: Mapped[Optional[int]] = mapped_column(
1451
+ ForeignKey("users.id", ondelete="SET NULL"),
1452
+ index=True,
1453
+ nullable=True,
1454
+ )
1455
+ name: Mapped[str]
1456
+ description: Mapped[Optional[str]]
1457
+ experiment: Mapped["Experiment"] = relationship("Experiment", back_populates="experiment_tags")
1458
+ dataset: Mapped["Dataset"] = relationship("Dataset", back_populates="experiment_tags")
1459
+ user: Mapped[Optional["User"]] = relationship("User")
1460
+
1461
+ __table_args__ = (UniqueConstraint("dataset_id", "name"),)
1462
+
1463
+
1464
+ class UserRole(HasId):
1227
1465
  __tablename__ = "user_roles"
1228
1466
  name: Mapped[UserRoleName] = mapped_column(unique=True, index=True)
1229
1467
  users: Mapped[list["User"]] = relationship("User", back_populates="role")
1230
1468
 
1231
1469
 
1232
- class User(Base):
1470
+ class User(HasId):
1233
1471
  __tablename__ = "users"
1234
1472
  user_role_id: Mapped[int] = mapped_column(
1235
1473
  ForeignKey("user_roles.id", ondelete="CASCADE"),
@@ -1339,7 +1577,7 @@ class OAuth2User(User):
1339
1577
  )
1340
1578
 
1341
1579
 
1342
- class PasswordResetToken(Base):
1580
+ class PasswordResetToken(HasId):
1343
1581
  __tablename__ = "password_reset_tokens"
1344
1582
  user_id: Mapped[int] = mapped_column(
1345
1583
  ForeignKey("users.id", ondelete="CASCADE"),
@@ -1352,7 +1590,7 @@ class PasswordResetToken(Base):
1352
1590
  __table_args__ = (dict(sqlite_autoincrement=True),)
1353
1591
 
1354
1592
 
1355
- class RefreshToken(Base):
1593
+ class RefreshToken(HasId):
1356
1594
  __tablename__ = "refresh_tokens"
1357
1595
  user_id: Mapped[int] = mapped_column(
1358
1596
  ForeignKey("users.id", ondelete="CASCADE"),
@@ -1364,7 +1602,7 @@ class RefreshToken(Base):
1364
1602
  __table_args__ = (dict(sqlite_autoincrement=True),)
1365
1603
 
1366
1604
 
1367
- class AccessToken(Base):
1605
+ class AccessToken(HasId):
1368
1606
  __tablename__ = "access_tokens"
1369
1607
  user_id: Mapped[int] = mapped_column(
1370
1608
  ForeignKey("users.id", ondelete="CASCADE"),
@@ -1381,7 +1619,7 @@ class AccessToken(Base):
1381
1619
  __table_args__ = (dict(sqlite_autoincrement=True),)
1382
1620
 
1383
1621
 
1384
- class ApiKey(Base):
1622
+ class ApiKey(HasId):
1385
1623
  __tablename__ = "api_keys"
1386
1624
  user_id: Mapped[int] = mapped_column(
1387
1625
  ForeignKey("users.id", ondelete="CASCADE"),
@@ -1398,7 +1636,7 @@ class ApiKey(Base):
1398
1636
  CostType: TypeAlias = Literal["DEFAULT", "OVERRIDE"]
1399
1637
 
1400
1638
 
1401
- class GenerativeModel(Base):
1639
+ class GenerativeModel(HasId):
1402
1640
  __tablename__ = "generative_models"
1403
1641
  name: Mapped[str] = mapped_column(String, nullable=False)
1404
1642
  provider: Mapped[str]
@@ -1447,7 +1685,7 @@ class GenerativeModel(Base):
1447
1685
  )
1448
1686
 
1449
1687
 
1450
- class TokenPrice(Base):
1688
+ class TokenPrice(HasId):
1451
1689
  __tablename__ = "token_prices"
1452
1690
  model_id: Mapped[int] = mapped_column(
1453
1691
  ForeignKey("generative_models.id", ondelete="CASCADE"),
@@ -1473,7 +1711,7 @@ class TokenPrice(Base):
1473
1711
  )
1474
1712
 
1475
1713
 
1476
- class PromptLabel(Base):
1714
+ class PromptLabel(HasId):
1477
1715
  __tablename__ = "prompt_labels"
1478
1716
  name: Mapped[str] = mapped_column(String, unique=True, index=True, nullable=False)
1479
1717
  description: Mapped[Optional[str]]
@@ -1487,7 +1725,7 @@ class PromptLabel(Base):
1487
1725
  )
1488
1726
 
1489
1727
 
1490
- class Prompt(Base):
1728
+ class Prompt(HasId):
1491
1729
  __tablename__ = "prompts"
1492
1730
  source_prompt_id: Mapped[Optional[int]] = mapped_column(
1493
1731
  ForeignKey("prompts.id", ondelete="SET NULL"),
@@ -1524,7 +1762,7 @@ class Prompt(Base):
1524
1762
  )
1525
1763
 
1526
1764
 
1527
- class PromptPromptLabel(Base):
1765
+ class PromptPromptLabel(HasId):
1528
1766
  __tablename__ = "prompts_prompt_labels"
1529
1767
  prompt_label_id: Mapped[int] = mapped_column(
1530
1768
  ForeignKey("prompt_labels.id", ondelete="CASCADE"),
@@ -1545,7 +1783,7 @@ class PromptPromptLabel(Base):
1545
1783
  __table_args__ = (UniqueConstraint("prompt_label_id", "prompt_id"),)
1546
1784
 
1547
1785
 
1548
- class PromptVersion(Base):
1786
+ class PromptVersion(HasId):
1549
1787
  __tablename__ = "prompt_versions"
1550
1788
 
1551
1789
  prompt_id: Mapped[int] = mapped_column(
@@ -1594,7 +1832,7 @@ class PromptVersion(Base):
1594
1832
  )
1595
1833
 
1596
1834
 
1597
- class PromptVersionTag(Base):
1835
+ class PromptVersionTag(HasId):
1598
1836
  __tablename__ = "prompt_version_tags"
1599
1837
 
1600
1838
  name: Mapped[Identifier] = mapped_column(_Identifier, nullable=False)
@@ -1623,13 +1861,13 @@ class PromptVersionTag(Base):
1623
1861
  __table_args__ = (UniqueConstraint("name", "prompt_id"),)
1624
1862
 
1625
1863
 
1626
- class AnnotationConfig(Base):
1864
+ class AnnotationConfig(HasId):
1627
1865
  __tablename__ = "annotation_configs"
1628
1866
  name: Mapped[str] = mapped_column(String, nullable=False, unique=True)
1629
1867
  config: Mapped[AnnotationConfigType] = mapped_column(_AnnotationConfig, nullable=False)
1630
1868
 
1631
1869
 
1632
- class ProjectAnnotationConfig(Base):
1870
+ class ProjectAnnotationConfig(HasId):
1633
1871
  __tablename__ = "project_annotation_configs"
1634
1872
  project_id: Mapped[int] = mapped_column(
1635
1873
  ForeignKey("projects.id", ondelete="CASCADE"), nullable=False, index=True
@@ -1641,16 +1879,18 @@ class ProjectAnnotationConfig(Base):
1641
1879
  __table_args__ = (UniqueConstraint("project_id", "annotation_config_id"),)
1642
1880
 
1643
1881
 
1644
- class SpanCost(Base):
1882
+ class SpanCost(HasId):
1645
1883
  __tablename__ = "span_costs"
1646
1884
 
1647
1885
  span_rowid: Mapped[int] = mapped_column(
1648
1886
  ForeignKey("spans.id", ondelete="CASCADE"),
1649
1887
  nullable=False,
1888
+ index=True,
1650
1889
  )
1651
1890
  trace_rowid: Mapped[int] = mapped_column(
1652
1891
  ForeignKey("traces.id", ondelete="CASCADE"),
1653
1892
  nullable=False,
1893
+ index=True,
1654
1894
  )
1655
1895
  span_start_time: Mapped[datetime] = mapped_column(
1656
1896
  UtcTimeStamp,
@@ -1753,14 +1993,13 @@ class SpanCost(Base):
1753
1993
  self.total_tokens = (self.total_tokens or 0) + tokens
1754
1994
 
1755
1995
 
1756
- class SpanCostDetail(Base):
1996
+ class SpanCostDetail(HasId):
1757
1997
  __tablename__ = "span_cost_details"
1758
1998
  span_cost_id: Mapped[int] = mapped_column(
1759
1999
  ForeignKey("span_costs.id", ondelete="CASCADE"),
1760
2000
  nullable=False,
1761
- index=True,
1762
2001
  )
1763
- token_type: Mapped[str]
2002
+ token_type: Mapped[str] = mapped_column(index=True)
1764
2003
  is_prompt: Mapped[bool]
1765
2004
 
1766
2005
  cost: Mapped[Optional[float]]