opik 1.9.41__py3-none-any.whl → 1.9.86__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.
Files changed (192) hide show
  1. opik/api_objects/attachment/attachment_context.py +36 -0
  2. opik/api_objects/attachment/attachments_extractor.py +153 -0
  3. opik/api_objects/attachment/client.py +1 -0
  4. opik/api_objects/attachment/converters.py +2 -0
  5. opik/api_objects/attachment/decoder.py +18 -0
  6. opik/api_objects/attachment/decoder_base64.py +83 -0
  7. opik/api_objects/attachment/decoder_helpers.py +137 -0
  8. opik/api_objects/constants.py +2 -0
  9. opik/api_objects/dataset/dataset.py +133 -40
  10. opik/api_objects/dataset/rest_operations.py +2 -0
  11. opik/api_objects/experiment/experiment.py +6 -0
  12. opik/api_objects/helpers.py +8 -4
  13. opik/api_objects/local_recording.py +6 -5
  14. opik/api_objects/observation_data.py +101 -0
  15. opik/api_objects/opik_client.py +78 -45
  16. opik/api_objects/opik_query_language.py +9 -3
  17. opik/api_objects/prompt/chat/chat_prompt.py +18 -1
  18. opik/api_objects/prompt/client.py +8 -1
  19. opik/api_objects/span/span_data.py +3 -88
  20. opik/api_objects/threads/threads_client.py +7 -4
  21. opik/api_objects/trace/trace_data.py +3 -74
  22. opik/api_objects/validation_helpers.py +3 -3
  23. opik/cli/exports/__init__.py +131 -0
  24. opik/cli/exports/dataset.py +278 -0
  25. opik/cli/exports/experiment.py +784 -0
  26. opik/cli/exports/project.py +685 -0
  27. opik/cli/exports/prompt.py +578 -0
  28. opik/cli/exports/utils.py +406 -0
  29. opik/cli/harbor.py +39 -0
  30. opik/cli/imports/__init__.py +439 -0
  31. opik/cli/imports/dataset.py +143 -0
  32. opik/cli/imports/experiment.py +1192 -0
  33. opik/cli/imports/project.py +262 -0
  34. opik/cli/imports/prompt.py +177 -0
  35. opik/cli/imports/utils.py +280 -0
  36. opik/cli/main.py +14 -12
  37. opik/config.py +12 -1
  38. opik/datetime_helpers.py +12 -0
  39. opik/decorator/arguments_helpers.py +4 -1
  40. opik/decorator/base_track_decorator.py +111 -37
  41. opik/decorator/context_manager/span_context_manager.py +5 -1
  42. opik/decorator/generator_wrappers.py +5 -4
  43. opik/decorator/span_creation_handler.py +13 -4
  44. opik/evaluation/engine/engine.py +111 -28
  45. opik/evaluation/engine/evaluation_tasks_executor.py +71 -19
  46. opik/evaluation/evaluator.py +12 -0
  47. opik/evaluation/metrics/conversation/llm_judges/conversational_coherence/metric.py +3 -1
  48. opik/evaluation/metrics/conversation/llm_judges/session_completeness/metric.py +3 -1
  49. opik/evaluation/metrics/conversation/llm_judges/user_frustration/metric.py +3 -1
  50. opik/evaluation/metrics/heuristics/equals.py +11 -7
  51. opik/evaluation/metrics/llm_judges/answer_relevance/metric.py +3 -1
  52. opik/evaluation/metrics/llm_judges/context_precision/metric.py +3 -1
  53. opik/evaluation/metrics/llm_judges/context_recall/metric.py +3 -1
  54. opik/evaluation/metrics/llm_judges/factuality/metric.py +1 -1
  55. opik/evaluation/metrics/llm_judges/g_eval/metric.py +3 -1
  56. opik/evaluation/metrics/llm_judges/hallucination/metric.py +3 -1
  57. opik/evaluation/metrics/llm_judges/moderation/metric.py +3 -1
  58. opik/evaluation/metrics/llm_judges/structure_output_compliance/metric.py +3 -1
  59. opik/evaluation/metrics/llm_judges/syc_eval/metric.py +4 -2
  60. opik/evaluation/metrics/llm_judges/trajectory_accuracy/metric.py +3 -1
  61. opik/evaluation/metrics/llm_judges/usefulness/metric.py +3 -1
  62. opik/evaluation/metrics/ragas_metric.py +43 -23
  63. opik/evaluation/models/litellm/litellm_chat_model.py +7 -2
  64. opik/evaluation/models/litellm/util.py +4 -20
  65. opik/evaluation/models/models_factory.py +19 -5
  66. opik/evaluation/rest_operations.py +3 -3
  67. opik/evaluation/threads/helpers.py +3 -2
  68. opik/file_upload/file_uploader.py +13 -0
  69. opik/file_upload/upload_options.py +2 -0
  70. opik/integrations/adk/legacy_opik_tracer.py +9 -11
  71. opik/integrations/adk/opik_tracer.py +2 -2
  72. opik/integrations/adk/patchers/adk_otel_tracer/opik_adk_otel_tracer.py +2 -2
  73. opik/integrations/dspy/callback.py +100 -14
  74. opik/integrations/dspy/parsers.py +168 -0
  75. opik/integrations/harbor/__init__.py +17 -0
  76. opik/integrations/harbor/experiment_service.py +269 -0
  77. opik/integrations/harbor/opik_tracker.py +528 -0
  78. opik/integrations/haystack/opik_tracer.py +2 -2
  79. opik/integrations/langchain/__init__.py +15 -2
  80. opik/integrations/langchain/langgraph_tracer_injector.py +88 -0
  81. opik/integrations/langchain/opik_tracer.py +258 -160
  82. opik/integrations/langchain/provider_usage_extractors/langchain_run_helpers/helpers.py +7 -4
  83. opik/integrations/llama_index/callback.py +43 -6
  84. opik/integrations/openai/agents/opik_tracing_processor.py +8 -10
  85. opik/integrations/openai/opik_tracker.py +99 -4
  86. opik/integrations/openai/videos/__init__.py +9 -0
  87. opik/integrations/openai/videos/binary_response_write_to_file_decorator.py +88 -0
  88. opik/integrations/openai/videos/videos_create_decorator.py +159 -0
  89. opik/integrations/openai/videos/videos_download_decorator.py +110 -0
  90. opik/message_processing/batching/base_batcher.py +14 -21
  91. opik/message_processing/batching/batch_manager.py +22 -10
  92. opik/message_processing/batching/batchers.py +32 -40
  93. opik/message_processing/batching/flushing_thread.py +0 -3
  94. opik/message_processing/emulation/emulator_message_processor.py +36 -1
  95. opik/message_processing/emulation/models.py +21 -0
  96. opik/message_processing/messages.py +9 -0
  97. opik/message_processing/preprocessing/__init__.py +0 -0
  98. opik/message_processing/preprocessing/attachments_preprocessor.py +70 -0
  99. opik/message_processing/preprocessing/batching_preprocessor.py +53 -0
  100. opik/message_processing/preprocessing/constants.py +1 -0
  101. opik/message_processing/preprocessing/file_upload_preprocessor.py +38 -0
  102. opik/message_processing/preprocessing/preprocessor.py +36 -0
  103. opik/message_processing/processors/__init__.py +0 -0
  104. opik/message_processing/processors/attachments_extraction_processor.py +146 -0
  105. opik/message_processing/{message_processors.py → processors/message_processors.py} +15 -1
  106. opik/message_processing/{message_processors_chain.py → processors/message_processors_chain.py} +3 -2
  107. opik/message_processing/{online_message_processor.py → processors/online_message_processor.py} +11 -9
  108. opik/message_processing/queue_consumer.py +4 -2
  109. opik/message_processing/streamer.py +71 -33
  110. opik/message_processing/streamer_constructors.py +36 -8
  111. opik/plugins/pytest/experiment_runner.py +1 -1
  112. opik/plugins/pytest/hooks.py +5 -3
  113. opik/rest_api/__init__.py +38 -0
  114. opik/rest_api/datasets/client.py +249 -148
  115. opik/rest_api/datasets/raw_client.py +356 -217
  116. opik/rest_api/experiments/client.py +26 -0
  117. opik/rest_api/experiments/raw_client.py +26 -0
  118. opik/rest_api/llm_provider_key/client.py +4 -4
  119. opik/rest_api/llm_provider_key/raw_client.py +4 -4
  120. opik/rest_api/llm_provider_key/types/provider_api_key_write_provider.py +2 -1
  121. opik/rest_api/manual_evaluation/client.py +101 -0
  122. opik/rest_api/manual_evaluation/raw_client.py +172 -0
  123. opik/rest_api/optimizations/client.py +0 -166
  124. opik/rest_api/optimizations/raw_client.py +0 -248
  125. opik/rest_api/projects/client.py +9 -0
  126. opik/rest_api/projects/raw_client.py +13 -0
  127. opik/rest_api/projects/types/project_metric_request_public_metric_type.py +4 -0
  128. opik/rest_api/prompts/client.py +130 -2
  129. opik/rest_api/prompts/raw_client.py +175 -0
  130. opik/rest_api/traces/client.py +101 -0
  131. opik/rest_api/traces/raw_client.py +120 -0
  132. opik/rest_api/types/__init__.py +46 -0
  133. opik/rest_api/types/audio_url.py +19 -0
  134. opik/rest_api/types/audio_url_public.py +19 -0
  135. opik/rest_api/types/audio_url_write.py +19 -0
  136. opik/rest_api/types/automation_rule_evaluator.py +38 -2
  137. opik/rest_api/types/automation_rule_evaluator_object_object_public.py +33 -2
  138. opik/rest_api/types/automation_rule_evaluator_public.py +33 -2
  139. opik/rest_api/types/automation_rule_evaluator_span_user_defined_metric_python.py +22 -0
  140. opik/rest_api/types/automation_rule_evaluator_span_user_defined_metric_python_public.py +22 -0
  141. opik/rest_api/types/automation_rule_evaluator_span_user_defined_metric_python_write.py +22 -0
  142. opik/rest_api/types/automation_rule_evaluator_update.py +27 -1
  143. opik/rest_api/types/automation_rule_evaluator_update_span_user_defined_metric_python.py +22 -0
  144. opik/rest_api/types/automation_rule_evaluator_write.py +27 -1
  145. opik/rest_api/types/dataset_item.py +1 -1
  146. opik/rest_api/types/dataset_item_batch.py +4 -0
  147. opik/rest_api/types/dataset_item_changes_public.py +5 -0
  148. opik/rest_api/types/dataset_item_compare.py +1 -1
  149. opik/rest_api/types/dataset_item_filter.py +4 -0
  150. opik/rest_api/types/dataset_item_page_compare.py +0 -1
  151. opik/rest_api/types/dataset_item_page_public.py +0 -1
  152. opik/rest_api/types/dataset_item_public.py +1 -1
  153. opik/rest_api/types/dataset_version_public.py +5 -0
  154. opik/rest_api/types/dataset_version_summary.py +5 -0
  155. opik/rest_api/types/dataset_version_summary_public.py +5 -0
  156. opik/rest_api/types/experiment.py +9 -0
  157. opik/rest_api/types/experiment_public.py +9 -0
  158. opik/rest_api/types/llm_as_judge_message_content.py +2 -0
  159. opik/rest_api/types/llm_as_judge_message_content_public.py +2 -0
  160. opik/rest_api/types/llm_as_judge_message_content_write.py +2 -0
  161. opik/rest_api/types/manual_evaluation_request_entity_type.py +1 -1
  162. opik/rest_api/types/project.py +1 -0
  163. opik/rest_api/types/project_detailed.py +1 -0
  164. opik/rest_api/types/project_metric_response_public_metric_type.py +4 -0
  165. opik/rest_api/types/project_reference.py +31 -0
  166. opik/rest_api/types/project_reference_public.py +31 -0
  167. opik/rest_api/types/project_stats_summary_item.py +1 -0
  168. opik/rest_api/types/prompt_version.py +1 -0
  169. opik/rest_api/types/prompt_version_detail.py +1 -0
  170. opik/rest_api/types/prompt_version_page_public.py +5 -0
  171. opik/rest_api/types/prompt_version_public.py +1 -0
  172. opik/rest_api/types/prompt_version_update.py +33 -0
  173. opik/rest_api/types/provider_api_key.py +5 -1
  174. opik/rest_api/types/provider_api_key_provider.py +2 -1
  175. opik/rest_api/types/provider_api_key_public.py +5 -1
  176. opik/rest_api/types/provider_api_key_public_provider.py +2 -1
  177. opik/rest_api/types/service_toggles_config.py +11 -1
  178. opik/rest_api/types/span_user_defined_metric_python_code.py +20 -0
  179. opik/rest_api/types/span_user_defined_metric_python_code_public.py +20 -0
  180. opik/rest_api/types/span_user_defined_metric_python_code_write.py +20 -0
  181. opik/types.py +36 -0
  182. opik/validation/chat_prompt_messages.py +241 -0
  183. opik/validation/feedback_score.py +3 -3
  184. opik/validation/validator.py +28 -0
  185. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/METADATA +5 -5
  186. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/RECORD +190 -141
  187. opik/cli/export.py +0 -791
  188. opik/cli/import_command.py +0 -575
  189. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/WHEEL +0 -0
  190. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/entry_points.txt +0 -0
  191. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/licenses/LICENSE +0 -0
  192. {opik-1.9.41.dist-info → opik-1.9.86.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ DatasetItemChangesPublic = typing.Dict[str, typing.Optional[typing.Any]]
@@ -12,7 +12,7 @@ from .json_node import JsonNode
12
12
 
13
13
  class DatasetItemCompare(UniversalBaseModel):
14
14
  id: typing.Optional[str] = None
15
- draft_item_id: typing.Optional[str] = None
15
+ dataset_item_id: typing.Optional[str] = None
16
16
  trace_id: typing.Optional[str] = None
17
17
  span_id: typing.Optional[str] = None
18
18
  source: DatasetItemCompareSource
@@ -8,6 +8,10 @@ from .dataset_item_filter_operator import DatasetItemFilterOperator
8
8
 
9
9
 
10
10
  class DatasetItemFilter(UniversalBaseModel):
11
+ """
12
+ Filters to select dataset items to delete within the specified dataset. Must be used with 'dataset_id'. Mutually exclusive with 'item_ids'. Empty array means 'delete all items in the dataset'.
13
+ """
14
+
11
15
  field: typing.Optional[str] = None
12
16
  operator: typing.Optional[DatasetItemFilterOperator] = None
13
17
  key: typing.Optional[str] = None
@@ -19,7 +19,6 @@ class DatasetItemPageCompare(UniversalBaseModel):
19
19
  sortable_by: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="sortableBy")] = (
20
20
  None
21
21
  )
22
- has_draft: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="hasDraft")] = None
23
22
 
24
23
  if IS_PYDANTIC_V2:
25
24
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -19,7 +19,6 @@ class DatasetItemPagePublic(UniversalBaseModel):
19
19
  sortable_by: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="sortableBy")] = (
20
20
  None
21
21
  )
22
- has_draft: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="hasDraft")] = None
23
22
 
24
23
  if IS_PYDANTIC_V2:
25
24
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -12,7 +12,7 @@ from .json_node import JsonNode
12
12
 
13
13
  class DatasetItemPublic(UniversalBaseModel):
14
14
  id: typing.Optional[str] = None
15
- draft_item_id: typing.Optional[str] = None
15
+ dataset_item_id: typing.Optional[str] = None
16
16
  trace_id: typing.Optional[str] = None
17
17
  span_id: typing.Optional[str] = None
18
18
  source: DatasetItemPublicSource
@@ -17,6 +17,11 @@ class DatasetVersionPublic(UniversalBaseModel):
17
17
  Indicates whether this is the latest version of the dataset
18
18
  """
19
19
 
20
+ version_name: typing.Optional[str] = pydantic.Field(default=None)
21
+ """
22
+ Sequential version name formatted as 'v1', 'v2', etc.
23
+ """
24
+
20
25
  items_total: typing.Optional[int] = pydantic.Field(default=None)
21
26
  """
22
27
  Total number of items in this version
@@ -21,6 +21,11 @@ class DatasetVersionSummary(UniversalBaseModel):
21
21
  Hash of the version content
22
22
  """
23
23
 
24
+ version_name: typing.Optional[str] = pydantic.Field(default=None)
25
+ """
26
+ Sequential version name formatted as 'v1', 'v2', etc.
27
+ """
28
+
24
29
  change_description: typing.Optional[str] = pydantic.Field(default=None)
25
30
  """
26
31
  Description of changes in this version
@@ -21,6 +21,11 @@ class DatasetVersionSummaryPublic(UniversalBaseModel):
21
21
  Hash of the version content
22
22
  """
23
23
 
24
+ version_name: typing.Optional[str] = pydantic.Field(default=None)
25
+ """
26
+ Sequential version name formatted as 'v1', 'v2', etc.
27
+ """
28
+
24
29
  change_description: typing.Optional[str] = pydantic.Field(default=None)
25
30
  """
26
31
  Description of changes in this version
@@ -6,6 +6,7 @@ import typing
6
6
  import pydantic
7
7
  from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
8
  from .comment import Comment
9
+ from .dataset_version_summary import DatasetVersionSummary
9
10
  from .experiment_score import ExperimentScore
10
11
  from .experiment_status import ExperimentStatus
11
12
  from .experiment_type import ExperimentType
@@ -19,8 +20,10 @@ class Experiment(UniversalBaseModel):
19
20
  id: typing.Optional[str] = None
20
21
  dataset_name: str
21
22
  dataset_id: typing.Optional[str] = None
23
+ project_id: typing.Optional[str] = None
22
24
  name: typing.Optional[str] = None
23
25
  metadata: typing.Optional[JsonListString] = None
26
+ tags: typing.Optional[typing.List[str]] = None
24
27
  type: typing.Optional[ExperimentType] = None
25
28
  optimization_id: typing.Optional[str] = None
26
29
  feedback_scores: typing.Optional[typing.List[FeedbackScoreAverage]] = None
@@ -38,6 +41,12 @@ class Experiment(UniversalBaseModel):
38
41
  experiment_scores: typing.Optional[typing.List[ExperimentScore]] = None
39
42
  prompt_version: typing.Optional[PromptVersionLink] = None
40
43
  prompt_versions: typing.Optional[typing.List[PromptVersionLink]] = None
44
+ dataset_version_id: typing.Optional[str] = pydantic.Field(default=None)
45
+ """
46
+ ID of the dataset version this experiment is linked to. If not provided at creation, experiment will be automatically linked to the latest version.
47
+ """
48
+
49
+ dataset_version_summary: typing.Optional[DatasetVersionSummary] = None
41
50
 
42
51
  if IS_PYDANTIC_V2:
43
52
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -6,6 +6,7 @@ import typing
6
6
  import pydantic
7
7
  from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
8
  from .comment_public import CommentPublic
9
+ from .dataset_version_summary_public import DatasetVersionSummaryPublic
9
10
  from .experiment_public_status import ExperimentPublicStatus
10
11
  from .experiment_public_type import ExperimentPublicType
11
12
  from .experiment_score_public import ExperimentScorePublic
@@ -19,8 +20,10 @@ class ExperimentPublic(UniversalBaseModel):
19
20
  id: typing.Optional[str] = None
20
21
  dataset_name: str
21
22
  dataset_id: typing.Optional[str] = None
23
+ project_id: typing.Optional[str] = None
22
24
  name: typing.Optional[str] = None
23
25
  metadata: typing.Optional[JsonListStringPublic] = None
26
+ tags: typing.Optional[typing.List[str]] = None
24
27
  type: typing.Optional[ExperimentPublicType] = None
25
28
  optimization_id: typing.Optional[str] = None
26
29
  feedback_scores: typing.Optional[typing.List[FeedbackScoreAveragePublic]] = None
@@ -38,6 +41,12 @@ class ExperimentPublic(UniversalBaseModel):
38
41
  experiment_scores: typing.Optional[typing.List[ExperimentScorePublic]] = None
39
42
  prompt_version: typing.Optional[PromptVersionLinkPublic] = None
40
43
  prompt_versions: typing.Optional[typing.List[PromptVersionLinkPublic]] = None
44
+ dataset_version_id: typing.Optional[str] = pydantic.Field(default=None)
45
+ """
46
+ ID of the dataset version this experiment is linked to. If not provided at creation, experiment will be automatically linked to the latest version.
47
+ """
48
+
49
+ dataset_version_summary: typing.Optional[DatasetVersionSummaryPublic] = None
41
50
 
42
51
  if IS_PYDANTIC_V2:
43
52
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -4,6 +4,7 @@ import typing
4
4
 
5
5
  import pydantic
6
6
  from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .audio_url import AudioUrl
7
8
  from .image_url import ImageUrl
8
9
  from .video_url import VideoUrl
9
10
 
@@ -13,6 +14,7 @@ class LlmAsJudgeMessageContent(UniversalBaseModel):
13
14
  text: typing.Optional[str] = None
14
15
  image_url: typing.Optional[ImageUrl] = None
15
16
  video_url: typing.Optional[VideoUrl] = None
17
+ audio_url: typing.Optional[AudioUrl] = None
16
18
 
17
19
  if IS_PYDANTIC_V2:
18
20
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -4,6 +4,7 @@ import typing
4
4
 
5
5
  import pydantic
6
6
  from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .audio_url_public import AudioUrlPublic
7
8
  from .image_url_public import ImageUrlPublic
8
9
  from .video_url_public import VideoUrlPublic
9
10
 
@@ -13,6 +14,7 @@ class LlmAsJudgeMessageContentPublic(UniversalBaseModel):
13
14
  text: typing.Optional[str] = None
14
15
  image_url: typing.Optional[ImageUrlPublic] = None
15
16
  video_url: typing.Optional[VideoUrlPublic] = None
17
+ audio_url: typing.Optional[AudioUrlPublic] = None
16
18
 
17
19
  if IS_PYDANTIC_V2:
18
20
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -4,6 +4,7 @@ import typing
4
4
 
5
5
  import pydantic
6
6
  from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .audio_url_write import AudioUrlWrite
7
8
  from .image_url_write import ImageUrlWrite
8
9
  from .video_url_write import VideoUrlWrite
9
10
 
@@ -13,6 +14,7 @@ class LlmAsJudgeMessageContentWrite(UniversalBaseModel):
13
14
  text: typing.Optional[str] = None
14
15
  image_url: typing.Optional[ImageUrlWrite] = None
15
16
  video_url: typing.Optional[VideoUrlWrite] = None
17
+ audio_url: typing.Optional[AudioUrlWrite] = None
16
18
 
17
19
  if IS_PYDANTIC_V2:
18
20
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -2,4 +2,4 @@
2
2
 
3
3
  import typing
4
4
 
5
- ManualEvaluationRequestEntityType = typing.Union[typing.Literal["trace", "thread"], typing.Any]
5
+ ManualEvaluationRequestEntityType = typing.Union[typing.Literal["trace", "thread", "span"], typing.Any]
@@ -27,6 +27,7 @@ class Project(UniversalBaseModel):
27
27
  total_estimated_cost_sum: typing.Optional[float] = None
28
28
  usage: typing.Optional[typing.Dict[str, float]] = None
29
29
  trace_count: typing.Optional[int] = None
30
+ thread_count: typing.Optional[int] = None
30
31
  guardrails_failed_count: typing.Optional[int] = None
31
32
  error_count: typing.Optional[ErrorCountWithDeviation] = None
32
33
 
@@ -27,6 +27,7 @@ class ProjectDetailed(UniversalBaseModel):
27
27
  total_estimated_cost_sum: typing.Optional[float] = None
28
28
  usage: typing.Optional[typing.Dict[str, float]] = None
29
29
  trace_count: typing.Optional[int] = None
30
+ thread_count: typing.Optional[int] = None
30
31
  guardrails_failed_count: typing.Optional[int] = None
31
32
  error_count: typing.Optional[ErrorCountWithDeviationDetailed] = None
32
33
 
@@ -13,6 +13,10 @@ ProjectMetricResponsePublicMetricType = typing.Union[
13
13
  "THREAD_COUNT",
14
14
  "THREAD_DURATION",
15
15
  "THREAD_FEEDBACK_SCORES",
16
+ "SPAN_FEEDBACK_SCORES",
17
+ "SPAN_COUNT",
18
+ "SPAN_DURATION",
19
+ "SPAN_TOKEN_USAGE",
16
20
  ],
17
21
  typing.Any,
18
22
  ]
@@ -0,0 +1,31 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class ProjectReference(UniversalBaseModel):
10
+ """
11
+ Project reference with ID and name
12
+ """
13
+
14
+ project_id: str = pydantic.Field()
15
+ """
16
+ Project ID
17
+ """
18
+
19
+ project_name: str = pydantic.Field()
20
+ """
21
+ Project name
22
+ """
23
+
24
+ if IS_PYDANTIC_V2:
25
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
26
+ else:
27
+
28
+ class Config:
29
+ frozen = True
30
+ smart_union = True
31
+ extra = pydantic.Extra.allow
@@ -0,0 +1,31 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class ProjectReferencePublic(UniversalBaseModel):
10
+ """
11
+ Project reference with ID and name
12
+ """
13
+
14
+ project_id: str = pydantic.Field()
15
+ """
16
+ Project ID
17
+ """
18
+
19
+ project_name: str = pydantic.Field()
20
+ """
21
+ Project name
22
+ """
23
+
24
+ if IS_PYDANTIC_V2:
25
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
26
+ else:
27
+
28
+ class Config:
29
+ frozen = True
30
+ smart_union = True
31
+ extra = pydantic.Extra.allow
@@ -17,6 +17,7 @@ class ProjectStatsSummaryItem(UniversalBaseModel):
17
17
  total_estimated_cost_sum: typing.Optional[float] = None
18
18
  usage: typing.Optional[typing.Dict[str, float]] = None
19
19
  trace_count: typing.Optional[int] = None
20
+ thread_count: typing.Optional[int] = None
20
21
  guardrails_failed_count: typing.Optional[int] = None
21
22
  error_count: typing.Optional[ErrorCountWithDeviation] = None
22
23
 
@@ -26,6 +26,7 @@ class PromptVersion(UniversalBaseModel):
26
26
  metadata: typing.Optional[JsonNode] = None
27
27
  type: typing.Optional[PromptVersionType] = None
28
28
  change_description: typing.Optional[str] = None
29
+ tags: typing.Optional[typing.List[str]] = None
29
30
  variables: typing.Optional[typing.List[str]] = None
30
31
  template_structure: typing.Optional[PromptVersionTemplateStructure] = None
31
32
  created_at: typing.Optional[dt.datetime] = None
@@ -26,6 +26,7 @@ class PromptVersionDetail(UniversalBaseModel):
26
26
  metadata: typing.Optional[JsonNodeDetail] = None
27
27
  type: typing.Optional[PromptVersionDetailType] = None
28
28
  change_description: typing.Optional[str] = None
29
+ tags: typing.Optional[typing.List[str]] = None
29
30
  variables: typing.Optional[typing.List[str]] = None
30
31
  template_structure: typing.Optional[PromptVersionDetailTemplateStructure] = None
31
32
  created_at: typing.Optional[dt.datetime] = None
@@ -3,7 +3,9 @@
3
3
  import typing
4
4
 
5
5
  import pydantic
6
+ import typing_extensions
6
7
  from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+ from ..core.serialization import FieldMetadata
7
9
  from .prompt_version_public import PromptVersionPublic
8
10
 
9
11
 
@@ -12,6 +14,9 @@ class PromptVersionPagePublic(UniversalBaseModel):
12
14
  size: typing.Optional[int] = None
13
15
  total: typing.Optional[int] = None
14
16
  content: typing.Optional[typing.List[PromptVersionPublic]] = None
17
+ sortable_by: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="sortableBy")] = (
18
+ None
19
+ )
15
20
 
16
21
  if IS_PYDANTIC_V2:
17
22
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -26,6 +26,7 @@ class PromptVersionPublic(UniversalBaseModel):
26
26
  metadata: typing.Optional[JsonNodePublic] = None
27
27
  type: typing.Optional[PromptVersionPublicType] = None
28
28
  change_description: typing.Optional[str] = None
29
+ tags: typing.Optional[typing.List[str]] = None
29
30
  template_structure: typing.Optional[PromptVersionPublicTemplateStructure] = None
30
31
  created_at: typing.Optional[dt.datetime] = None
31
32
  created_by: typing.Optional[str] = None
@@ -0,0 +1,33 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class PromptVersionUpdate(UniversalBaseModel):
10
+ """
11
+ Update to apply to prompt versions.
12
+ Note: Prompt versions are immutable by design.
13
+ Only organizational properties (such as tags etc.) can be updated.
14
+ Core properties like template, metadata etc. cannot be modified after creation.
15
+ """
16
+
17
+ tags: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
18
+ """
19
+ Tags to set or merge with existing tags. Follows PATCH semantics:
20
+ - If merge_tags is true, these tags will be added to existing tags.
21
+ - If merge_tags is false, these tags will replace all existing tags.
22
+ - null: preserve existing tags (no change).
23
+ - empty set: clear all tags merge_tags is false.
24
+ """
25
+
26
+ if IS_PYDANTIC_V2:
27
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
28
+ else:
29
+
30
+ class Config:
31
+ frozen = True
32
+ smart_union = True
33
+ extra = pydantic.Extra.allow
@@ -15,7 +15,7 @@ class ProviderApiKey(UniversalBaseModel):
15
15
  name: typing.Optional[str] = None
16
16
  provider_name: typing.Optional[str] = pydantic.Field(default=None)
17
17
  """
18
- Provider name - required for custom LLM providers to uniquely identify them (e.g., 'ollama', 'vllm'). Must not be blank for custom providers. Should not be set for standard providers (OpenAI, Anthropic, etc.). This requirement is conditional and validation is enforced programmatically.
18
+ Provider name - required for custom LLM and Bedrock providers to uniquely identify them (e.g., 'ollama', 'vllm', 'Bedrock us-east-1'). Must not be blank for custom and Bedrock providers. Should not be set for standard providers (OpenAI, Anthropic, etc.). This requirement is conditional and validation is enforced programmatically.
19
19
  """
20
20
 
21
21
  headers: typing.Optional[typing.Dict[str, str]] = None
@@ -25,6 +25,10 @@ class ProviderApiKey(UniversalBaseModel):
25
25
  created_by: typing.Optional[str] = None
26
26
  last_updated_at: typing.Optional[dt.datetime] = None
27
27
  last_updated_by: typing.Optional[str] = None
28
+ read_only: typing.Optional[bool] = pydantic.Field(default=None)
29
+ """
30
+ If true, this provider is system-managed and cannot be edited or deleted
31
+ """
28
32
 
29
33
  if IS_PYDANTIC_V2:
30
34
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -3,5 +3,6 @@
3
3
  import typing
4
4
 
5
5
  ProviderApiKeyProvider = typing.Union[
6
- typing.Literal["openai", "anthropic", "gemini", "openrouter", "vertex-ai", "custom-llm"], typing.Any
6
+ typing.Literal["openai", "anthropic", "gemini", "openrouter", "vertex-ai", "bedrock", "custom-llm", "opik-free"],
7
+ typing.Any,
7
8
  ]
@@ -15,7 +15,7 @@ class ProviderApiKeyPublic(UniversalBaseModel):
15
15
  name: typing.Optional[str] = None
16
16
  provider_name: typing.Optional[str] = pydantic.Field(default=None)
17
17
  """
18
- Provider name - required for custom LLM providers to uniquely identify them (e.g., 'ollama', 'vllm'). Must not be blank for custom providers. Should not be set for standard providers (OpenAI, Anthropic, etc.). This requirement is conditional and validation is enforced programmatically.
18
+ Provider name - required for custom LLM and Bedrock providers to uniquely identify them (e.g., 'ollama', 'vllm', 'Bedrock us-east-1'). Must not be blank for custom and Bedrock providers. Should not be set for standard providers (OpenAI, Anthropic, etc.). This requirement is conditional and validation is enforced programmatically.
19
19
  """
20
20
 
21
21
  headers: typing.Optional[typing.Dict[str, str]] = None
@@ -25,6 +25,10 @@ class ProviderApiKeyPublic(UniversalBaseModel):
25
25
  created_by: typing.Optional[str] = None
26
26
  last_updated_at: typing.Optional[dt.datetime] = None
27
27
  last_updated_by: typing.Optional[str] = None
28
+ read_only: typing.Optional[bool] = pydantic.Field(default=None)
29
+ """
30
+ If true, this provider is system-managed and cannot be edited or deleted
31
+ """
28
32
 
29
33
  if IS_PYDANTIC_V2:
30
34
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -3,5 +3,6 @@
3
3
  import typing
4
4
 
5
5
  ProviderApiKeyPublicProvider = typing.Union[
6
- typing.Literal["openai", "anthropic", "gemini", "openrouter", "vertex-ai", "custom-llm"], typing.Any
6
+ typing.Literal["openai", "anthropic", "gemini", "openrouter", "vertex-ai", "bedrock", "custom-llm", "opik-free"],
7
+ typing.Any,
7
8
  ]
@@ -14,6 +14,9 @@ class ServiceTogglesConfig(UniversalBaseModel):
14
14
  bool, FieldMetadata(alias="traceThreadPythonEvaluatorEnabled")
15
15
  ]
16
16
  span_llm_as_judge_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="spanLlmAsJudgeEnabled")]
17
+ span_user_defined_metric_python_enabled: typing_extensions.Annotated[
18
+ bool, FieldMetadata(alias="spanUserDefinedMetricPythonEnabled")
19
+ ]
17
20
  guardrails_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="guardrailsEnabled")]
18
21
  opik_ai_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="opikAIEnabled")]
19
22
  alerts_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="alertsEnabled")]
@@ -21,8 +24,15 @@ class ServiceTogglesConfig(UniversalBaseModel):
21
24
  csv_upload_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="csvUploadEnabled")]
22
25
  export_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="exportEnabled")]
23
26
  optimization_studio_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="optimizationStudioEnabled")]
24
- dashboards_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="dashboardsEnabled")]
25
27
  dataset_versioning_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="datasetVersioningEnabled")]
28
+ openai_provider_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="openaiProviderEnabled")]
29
+ anthropic_provider_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="anthropicProviderEnabled")]
30
+ gemini_provider_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="geminiProviderEnabled")]
31
+ openrouter_provider_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="openrouterProviderEnabled")]
32
+ vertexai_provider_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="vertexaiProviderEnabled")]
33
+ bedrock_provider_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="bedrockProviderEnabled")]
34
+ customllm_provider_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="customllmProviderEnabled")]
35
+ collaborators_tab_enabled: typing_extensions.Annotated[bool, FieldMetadata(alias="collaboratorsTabEnabled")]
26
36
 
27
37
  if IS_PYDANTIC_V2:
28
38
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -0,0 +1,20 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class SpanUserDefinedMetricPythonCode(UniversalBaseModel):
10
+ metric: str
11
+ arguments: typing.Dict[str, str]
12
+
13
+ if IS_PYDANTIC_V2:
14
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
15
+ else:
16
+
17
+ class Config:
18
+ frozen = True
19
+ smart_union = True
20
+ extra = pydantic.Extra.allow
@@ -0,0 +1,20 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class SpanUserDefinedMetricPythonCodePublic(UniversalBaseModel):
10
+ metric: str
11
+ arguments: typing.Dict[str, str]
12
+
13
+ if IS_PYDANTIC_V2:
14
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
15
+ else:
16
+
17
+ class Config:
18
+ frozen = True
19
+ smart_union = True
20
+ extra = pydantic.Extra.allow
@@ -0,0 +1,20 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+
8
+
9
+ class SpanUserDefinedMetricPythonCodeWrite(UniversalBaseModel):
10
+ metric: str
11
+ arguments: typing.Dict[str, str]
12
+
13
+ if IS_PYDANTIC_V2:
14
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
15
+ else:
16
+
17
+ class Config:
18
+ frozen = True
19
+ smart_union = True
20
+ extra = pydantic.Extra.allow
opik/types.py CHANGED
@@ -2,6 +2,7 @@ import enum
2
2
  import sys
3
3
  from typing import Literal, Optional
4
4
 
5
+ from pydantic import StrictStr
5
6
  from typing_extensions import TypedDict
6
7
 
7
8
  if sys.version_info < (3, 11):
@@ -79,6 +80,41 @@ class FeedbackScoreDict(TypedDict):
79
80
  """An optional explanation or justification for the given score."""
80
81
 
81
82
 
83
+ class BatchFeedbackScoreDict(TypedDict):
84
+ """
85
+ A TypedDict representing a feedback score for batch operations.
86
+
87
+ This class defines the structure for feedback scores used in batch logging
88
+ operations, with a required id field and optional per-score project_name.
89
+ """
90
+
91
+ id: Required[str]
92
+ """
93
+ A unique identifier for the object this score should be assigned to.
94
+ Refers to either the trace_id, span_id or thread_id depending on how the score is logged.
95
+ Required for batch operations.
96
+ """
97
+
98
+ name: Required[str]
99
+ """The name of the feedback metric or criterion."""
100
+
101
+ value: Required[float]
102
+ """The numerical value of the feedback score."""
103
+
104
+ project_name: NotRequired[Optional[StrictStr]]
105
+ """
106
+ The name of the project for this specific score.
107
+ If not provided, falls back to the project_name parameter in the method call,
108
+ or the default project name configured in the Opik instance.
109
+ """
110
+
111
+ category_name: NotRequired[Optional[str]]
112
+ """An optional category name for the given score."""
113
+
114
+ reason: NotRequired[Optional[str]]
115
+ """An optional explanation or justification for the given score."""
116
+
117
+
82
118
  class ErrorInfoDict(TypedDict):
83
119
  """
84
120
  A TypedDict representing the information about the error occurred.