1use derive_builder::Builder;
2use serde::{Deserialize, Serialize};
3
4use crate::error::OpenAIError;
5use crate::types::chat::{ChatCompletionTool, ImageDetail, InputAudio, ResponseFormat};
6use crate::types::graders::{
7 GraderLabelModel, GraderPython, GraderScoreModel, GraderStringCheck, GraderTextSimilarity,
8};
9use crate::types::responses::{ResponseTextParam, Tool};
10use crate::types::Metadata;
11
12pub use crate::types::responses::{EasyInputMessage, InputTextContent, ReasoningEffort};
14
15#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
22pub struct Eval {
23 pub object: String,
25 pub id: String,
27 pub name: String,
29 pub data_source_config: EvalDataSourceConfig,
31 pub testing_criteria: Vec<EvalTestingCriterion>,
33 pub created_at: u64,
35 pub metadata: Metadata,
36}
37
38#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
40#[serde(tag = "type", rename_all = "snake_case")]
41pub enum EvalDataSourceConfig {
42 Custom(EvalCustomDataSourceConfig),
44 Logs(EvalLogsDataSourceConfig),
46 StoredCompletions(EvalStoredCompletionsDataSourceConfig),
48}
49
50#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
52pub struct EvalCustomDataSourceConfig {
53 #[serde(rename = "type")]
55 pub r#type: String,
56 pub schema: serde_json::Value,
58}
59
60#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
62pub struct EvalLogsDataSourceConfig {
63 #[serde(rename = "type")]
65 pub r#type: String,
66 #[serde(skip_serializing_if = "Option::is_none")]
68 pub metadata: Option<Metadata>,
69 pub schema: serde_json::Value,
71}
72
73#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
75pub struct EvalStoredCompletionsDataSourceConfig {
76 #[serde(rename = "type")]
78 pub r#type: String,
79 #[serde(skip_serializing_if = "Option::is_none")]
81 pub metadata: Option<Metadata>,
82 pub schema: serde_json::Value,
84}
85
86#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
88#[serde(tag = "type", rename_all = "snake_case")]
89pub enum EvalTestingCriterion {
90 LabelModel(EvalGraderLabelModel),
92 StringCheck(EvalGraderStringCheck),
94 TextSimilarity(EvalGraderTextSimilarity),
96 Python(EvalGraderPython),
98 ScoreModel(EvalGraderScoreModel),
100}
101
102#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
104#[serde(transparent)]
105pub struct EvalGraderLabelModel(pub GraderLabelModel);
106
107#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
109#[serde(transparent)]
110pub struct EvalGraderStringCheck(pub GraderStringCheck);
111
112#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
114pub struct EvalGraderTextSimilarity {
115 #[serde(flatten)]
116 pub grader: GraderTextSimilarity,
117 pub pass_threshold: f64,
118}
119
120#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq)]
122#[serde(rename_all = "snake_case")]
123pub enum TextSimilarityMetric {
124 Cosine,
126 FuzzyMatch,
128 Bleu,
130 Gleu,
132 Meteor,
134 Rouge1,
136 Rouge2,
138 Rouge3,
140 Rouge4,
142 Rouge5,
144 RougeL,
146}
147
148#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
151pub struct EvalGraderPython {
152 #[serde(flatten)]
153 pub grader: GraderPython,
154 pub pass_threshold: Option<f64>,
155}
156
157#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
158pub struct SamplingParams {
159 #[serde(skip_serializing_if = "Option::is_none")]
161 pub seed: Option<i32>,
162 #[serde(skip_serializing_if = "Option::is_none")]
164 pub top_p: Option<f64>,
165 #[serde(skip_serializing_if = "Option::is_none")]
167 pub temperature: Option<f64>,
168 #[serde(skip_serializing_if = "Option::is_none")]
170 pub max_completion_tokens: Option<i32>,
171 #[serde(skip_serializing_if = "Option::is_none")]
173 pub reasoning_effort: Option<ReasoningEffort>,
174}
175
176#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
179pub struct EvalGraderScoreModel {
180 #[serde(flatten)]
181 pub grader: GraderScoreModel,
182 pub pass_threshold: Option<f64>,
184}
185
186#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
187pub struct EvalItem {
188 pub role: EvalItemRole,
191 pub content: EvalItemContent,
194}
195
196#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq)]
198#[serde(rename_all = "lowercase")]
199pub enum EvalItemRole {
200 User,
202 Assistant,
204 System,
206 Developer,
208}
209
210#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
212pub struct EvalItemContentOutputText {
213 pub text: String,
215}
216
217#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
219pub struct EvalItemInputImage {
220 pub image_url: String,
222 #[serde(skip_serializing_if = "Option::is_none")]
225 pub detail: Option<ImageDetail>,
226}
227
228#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
231#[serde(untagged)]
232pub enum EvalItemContent {
233 Array(Vec<EvalItemContentItem>),
235 Single(EvalItemContentItem),
237}
238
239#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
241#[serde(tag = "type", rename_all = "snake_case")]
242pub enum EvalItemContentItem {
243 InputText(InputTextContent),
245 OutputText(EvalItemContentOutputText),
247 InputImage(EvalItemInputImage),
249 InputAudio(InputAudio),
251 #[serde(untagged)]
253 Text(String),
254}
255
256#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
258pub struct EvalList {
259 pub object: String,
261 pub data: Vec<Eval>,
263 pub first_id: Option<String>,
265 pub last_id: Option<String>,
267 pub has_more: bool,
269}
270
271#[derive(Debug, Serialize, Clone, Builder, PartialEq, Default)]
272#[builder(name = "CreateEvalRequestArgs")]
273#[builder(pattern = "mutable")]
274#[builder(setter(into, strip_option), default)]
275#[builder(derive(Debug))]
276#[builder(build_fn(error = "OpenAIError"))]
277pub struct CreateEvalRequest {
278 pub name: Option<String>,
280 pub data_source_config: CreateEvalDataSourceConfig,
283 pub testing_criteria: Vec<CreateEvalTestingCriterion>,
287 #[serde(skip_serializing_if = "Option::is_none")]
288 pub metadata: Option<Metadata>,
289}
290
291#[derive(Debug, Serialize, Clone, PartialEq)]
292#[serde(tag = "type", rename_all = "snake_case")]
293pub enum CreateEvalDataSourceConfig {
294 Custom(CreateEvalCustomDataSourceConfig),
299 Logs(CreateEvalLogsDataSourceConfig),
302}
303
304impl Default for CreateEvalDataSourceConfig {
305 fn default() -> Self {
306 Self::Custom(CreateEvalCustomDataSourceConfig::default())
307 }
308}
309
310#[derive(Debug, Serialize, Clone, PartialEq, Builder, Default)]
311#[builder(name = "CreateEvalCustomDataSourceConfigArgs")]
312#[builder(pattern = "mutable")]
313#[builder(setter(into, strip_option), default)]
314#[builder(derive(Debug))]
315#[builder(build_fn(error = "OpenAIError"))]
316pub struct CreateEvalCustomDataSourceConfig {
317 pub item_schema: serde_json::Value,
319 #[serde(skip_serializing_if = "Option::is_none")]
322 pub include_sample_schema: Option<bool>,
323}
324
325#[derive(Debug, Serialize, Clone, PartialEq, Builder, Default)]
327#[builder(name = "CreateEvalLogsDataSourceConfigArgs")]
328#[builder(pattern = "mutable")]
329#[builder(setter(into, strip_option), default)]
330#[builder(derive(Debug))]
331#[builder(build_fn(error = "OpenAIError"))]
332pub struct CreateEvalLogsDataSourceConfig {
333 #[serde(skip_serializing_if = "Option::is_none")]
335 pub metadata: Option<Metadata>,
336}
337
338#[derive(Debug, Serialize, Clone, PartialEq)]
339#[serde(tag = "type", rename_all = "snake_case")]
340pub enum CreateEvalTestingCriterion {
341 LabelModel(CreateEvalLabelModelGrader),
344 StringCheck(EvalGraderStringCheck),
347 TextSimilarity(EvalGraderTextSimilarity),
349 Python(EvalGraderPython),
351 ScoreModel(EvalGraderScoreModel),
353}
354
355#[derive(Debug, Serialize, Clone, PartialEq, Builder, Default)]
357#[builder(name = "CreateEvalLabelModelGraderArgs")]
358#[builder(pattern = "mutable")]
359#[builder(setter(into, strip_option), default)]
360#[builder(derive(Debug))]
361#[builder(build_fn(error = "OpenAIError"))]
362pub struct CreateEvalLabelModelGrader {
363 pub name: String,
365 pub model: String,
367 pub input: Vec<CreateEvalItem>,
370 pub labels: Vec<String>,
372 pub passing_labels: Vec<String>,
374}
375
376#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
377pub struct SimpleInputMessage {
378 pub role: String,
380 pub content: String,
382}
383
384#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
386#[serde(tag = "type", rename_all = "snake_case")]
387pub enum CreateEvalItem {
388 Message(EvalItem),
394
395 #[serde(untagged)]
397 Simple(SimpleInputMessage),
398}
399
400#[derive(Debug, Serialize, Clone, Builder, PartialEq, Default)]
402#[builder(name = "UpdateEvalRequestArgs")]
403#[builder(pattern = "mutable")]
404#[builder(setter(into, strip_option), default)]
405#[builder(derive(Debug))]
406#[builder(build_fn(error = "OpenAIError"))]
407pub struct UpdateEvalRequest {
408 #[serde(skip_serializing_if = "Option::is_none")]
410 pub name: Option<String>,
411 #[serde(skip_serializing_if = "Option::is_none")]
413 pub metadata: Option<Metadata>,
414}
415
416#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
418pub struct DeleteEvalResponse {
419 pub object: String,
421 pub deleted: bool,
423 pub eval_id: String,
425}
426
427#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
431pub struct EvalRun {
432 pub object: String,
434 pub id: String,
436 pub eval_id: String,
438 pub status: EvalRunStatus,
440 pub model: Option<String>,
442 pub name: Option<String>,
444 pub created_at: u64,
446 pub report_url: String,
448 pub result_counts: EvalRunResultCounts,
450 pub per_model_usage: Option<Vec<EvalRunModelUsage>>,
452 pub per_testing_criteria_results: Option<Vec<EvalRunTestingCriteriaResult>>,
454 pub data_source: EvalRunDataSource,
456 pub metadata: Metadata,
458 pub error: Option<EvalApiError>,
460}
461
462#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq)]
464#[serde(rename_all = "snake_case")]
465pub enum EvalRunStatus {
466 Queued,
468 InProgress,
470 Completed,
472 Failed,
474 Canceled,
476}
477
478#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
480pub struct EvalRunResultCounts {
481 pub total: u32,
483 pub errored: u32,
485 pub failed: u32,
487 pub passed: u32,
489}
490
491#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
493pub struct EvalRunModelUsage {
494 pub model_name: String,
496 pub invocation_count: u32,
498 pub prompt_tokens: u32,
500 pub completion_tokens: u32,
502 pub total_tokens: u32,
504 pub cached_tokens: u32,
506}
507
508#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
510pub struct EvalRunTestingCriteriaResult {
511 pub testing_criteria: String,
513 pub passed: u32,
515 pub failed: u32,
517}
518
519#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
521#[serde(tag = "type", rename_all = "snake_case")]
522pub enum EvalRunDataSource {
523 Jsonl(CreateEvalJsonlRunDataSource),
525 Completions(CreateEvalCompletionsRunDataSource),
527 Responses(CreateEvalResponsesRunDataSource),
529}
530
531#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
533pub struct CreateEvalJsonlRunDataSource {
534 pub source: EvalJsonlSource,
536}
537
538#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
540#[serde(tag = "type", rename_all = "snake_case")]
541pub enum EvalJsonlSource {
542 FileContent(EvalJsonlFileContentSource),
544 FileId(EvalJsonlFileIdSource),
546}
547
548#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
550pub struct EvalJsonlFileContentSource {
551 pub content: Vec<EvalJsonlContentItem>,
553}
554
555#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
557pub struct EvalJsonlFileIdSource {
558 pub id: String,
560}
561
562#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
564pub struct EvalJsonlContentItem {
565 pub item: serde_json::Value,
567 #[serde(skip_serializing_if = "Option::is_none")]
569 pub sample: Option<serde_json::Value>,
570}
571
572#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
574pub struct CreateEvalCompletionsRunDataSource {
575 pub input_messages: EvalInputMessages,
579 #[serde(skip_serializing_if = "Option::is_none")]
581 pub sampling_params: Option<EvalSamplingParams>,
582 pub model: String,
584 pub source: EvalCompletionsSource,
586}
587
588#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
589pub struct TemplateInputMessages {
590 pub template: Vec<CreateEvalItem>,
593}
594
595#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
596pub struct ItemReference {
597 pub item_reference: String,
599}
600
601#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
603#[serde(tag = "type", rename_all = "snake_case")]
604pub enum EvalInputMessages {
605 Template(TemplateInputMessages),
607 ItemReference(ItemReference),
609}
610
611#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
613pub struct EvalSamplingParams {
614 #[serde(skip_serializing_if = "Option::is_none")]
616 pub seed: Option<i32>,
617 #[serde(skip_serializing_if = "Option::is_none")]
619 pub top_p: Option<f64>,
620 #[serde(skip_serializing_if = "Option::is_none")]
622 pub temperature: Option<f64>,
623 #[serde(skip_serializing_if = "Option::is_none")]
625 pub max_completion_tokens: Option<i32>,
626 #[serde(skip_serializing_if = "Option::is_none")]
628 pub reasoning_effort: Option<ReasoningEffort>,
629 #[serde(skip_serializing_if = "Option::is_none")]
631 pub response_format: Option<ResponseFormat>,
632 #[serde(skip_serializing_if = "Option::is_none")]
634 pub tools: Option<Vec<ChatCompletionTool>>,
635}
636
637#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
638pub struct EvalResponsesSamplingParams {
639 #[serde(skip_serializing_if = "Option::is_none")]
641 pub seed: Option<i32>,
642 #[serde(skip_serializing_if = "Option::is_none")]
644 pub top_p: Option<f64>,
645 #[serde(skip_serializing_if = "Option::is_none")]
647 pub temperature: Option<f64>,
648 #[serde(skip_serializing_if = "Option::is_none")]
650 pub max_completion_tokens: Option<u32>,
651 #[serde(skip_serializing_if = "Option::is_none")]
653 pub reasoning_effort: Option<ReasoningEffort>,
654 #[serde(skip_serializing_if = "Option::is_none")]
656 pub response_format: Option<ResponseFormat>,
657 #[serde(skip_serializing_if = "Option::is_none")]
659 pub tools: Option<Vec<Tool>>,
660 #[serde(skip_serializing_if = "Option::is_none")]
665 pub text: Option<ResponseTextParam>,
666}
667
668#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
670#[serde(tag = "type", rename_all = "snake_case")]
671pub enum EvalCompletionsSource {
672 FileContent(EvalJsonlFileContentSource),
674 FileId(EvalJsonlFileIdSource),
676 StoredCompletions(EvalStoredCompletionsSource),
678}
679
680#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
682pub struct EvalStoredCompletionsSource {
683 #[serde(skip_serializing_if = "Option::is_none")]
685 pub metadata: Option<Metadata>,
686 #[serde(skip_serializing_if = "Option::is_none")]
688 pub model: Option<String>,
689 #[serde(skip_serializing_if = "Option::is_none")]
691 pub created_after: Option<u64>,
692 #[serde(skip_serializing_if = "Option::is_none")]
694 pub created_before: Option<u64>,
695 #[serde(skip_serializing_if = "Option::is_none")]
697 pub limit: Option<i32>,
698}
699
700#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
702pub struct CreateEvalResponsesRunDataSource {
703 #[serde(skip_serializing_if = "Option::is_none")]
705 pub input_messages: Option<EvalInputMessages>,
706 #[serde(skip_serializing_if = "Option::is_none")]
708 pub sampling_params: Option<EvalResponsesSamplingParams>,
709 #[serde(skip_serializing_if = "Option::is_none")]
710 pub model: Option<String>,
711 pub source: EvalResponsesRunSource,
713}
714
715#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
717#[serde(tag = "type", rename_all = "snake_case")]
718pub enum EvalResponsesRunSource {
719 FileContent(EvalJsonlFileContentSource),
721 FileId(EvalJsonlFileIdSource),
723 Responses(EvalResponsesSource),
725}
726
727#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
729pub struct EvalResponsesSource {
730 #[serde(skip_serializing_if = "Option::is_none")]
732 pub metadata: Option<serde_json::Value>,
733 #[serde(skip_serializing_if = "Option::is_none")]
735 pub model: Option<String>,
736 #[serde(skip_serializing_if = "Option::is_none")]
738 pub instructions_search: Option<String>,
739 #[serde(skip_serializing_if = "Option::is_none")]
741 pub created_after: Option<u64>,
742 #[serde(skip_serializing_if = "Option::is_none")]
744 pub created_before: Option<u64>,
745 #[serde(skip_serializing_if = "Option::is_none")]
747 pub reasoning_effort: Option<ReasoningEffort>,
748 #[serde(skip_serializing_if = "Option::is_none")]
750 pub temperature: Option<f64>,
751 #[serde(skip_serializing_if = "Option::is_none")]
753 pub top_p: Option<f64>,
754 #[serde(skip_serializing_if = "Option::is_none")]
756 pub users: Option<Vec<String>>,
757 #[serde(skip_serializing_if = "Option::is_none")]
759 pub tools: Option<Vec<String>>,
760}
761
762#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
764pub struct EvalRunList {
765 pub object: String,
767 pub data: Vec<EvalRun>,
769 pub first_id: Option<String>,
771 pub last_id: Option<String>,
773 pub has_more: bool,
775}
776
777#[derive(Debug, Serialize, Clone, Builder, PartialEq, Default)]
779#[builder(name = "CreateEvalRunRequestArgs")]
780#[builder(pattern = "mutable")]
781#[builder(setter(into, strip_option), default)]
782#[builder(derive(Debug))]
783#[builder(build_fn(error = "OpenAIError"))]
784pub struct CreateEvalRunRequest {
785 #[serde(skip_serializing_if = "Option::is_none")]
787 pub name: Option<String>,
788 pub data_source: CreateEvalRunDataSource,
790 #[serde(skip_serializing_if = "Option::is_none")]
792 pub metadata: Option<Metadata>,
793}
794
795#[derive(Debug, Serialize, Clone, PartialEq)]
797#[serde(tag = "type", rename_all = "snake_case")]
798pub enum CreateEvalRunDataSource {
799 Jsonl(CreateEvalJsonlRunDataSource),
801 Completions(CreateEvalCompletionsRunDataSource),
803 Responses(CreateEvalResponsesRunDataSource),
805}
806
807impl Default for CreateEvalRunDataSource {
809 fn default() -> Self {
810 todo!()
811 }
812}
813
814#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
816pub struct DeleteEvalRunResponse {
817 pub object: String,
819 pub deleted: bool,
821 pub run_id: String,
823}
824
825#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
829pub struct EvalRunOutputItem {
830 pub object: String,
832 pub id: String,
834 pub run_id: String,
836 pub eval_id: String,
838 pub created_at: u64,
840 pub status: String,
842 pub datasource_item_id: u64,
844 pub datasource_item: serde_json::Value,
846 pub results: Vec<EvalRunOutputItemResult>,
848 pub sample: EvalRunOutputItemSample,
850}
851
852#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
854pub struct EvalRunOutputItemResult {
855 pub name: String,
857 pub score: f64,
859 pub passed: bool,
861 #[serde(skip_serializing_if = "Option::is_none")]
863 pub sample: Option<serde_json::Value>,
864}
865
866#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
867pub struct SimpleOutputMessage {
868 pub role: String,
869 pub content: String,
870}
871
872#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
874pub struct EvalRunOutputItemSample {
875 pub input: Vec<SimpleInputMessage>,
877 pub output: Vec<SimpleOutputMessage>,
879 pub finish_reason: String,
881 pub model: String,
883 pub usage: EvalRunOutputItemUsage,
885 pub error: Option<EvalApiError>,
887 pub temperature: f64,
889 pub max_completion_tokens: i32,
891 pub top_p: f64,
893 pub seed: i32,
895}
896
897#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
899pub struct EvalRunOutputItemUsage {
900 pub total_tokens: i32,
902 pub completion_tokens: i32,
904 pub prompt_tokens: i32,
906 pub cached_tokens: i32,
908}
909
910#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
912pub struct EvalRunOutputItemList {
913 pub object: String,
915 pub data: Vec<EvalRunOutputItem>,
917 pub first_id: Option<String>,
919 pub last_id: Option<String>,
921 pub has_more: bool,
923}
924
925#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Default)]
927pub struct EvalApiError {
928 pub code: String,
930 pub message: String,
932}