batch_mode_process_response/
process_batch_output_and_errors.rs1crate::ix!();
3
4pub async fn process_batch_output_and_errors<T>(
8 workspace: &dyn BatchWorkspaceInterface,
9 batch_execution_result: &BatchExecutionResult,
10 expected_content_type: &ExpectedContentType,
11) -> Result<(), BatchProcessingError>
12where
13 T: 'static + Send + Sync + DeserializeOwned + Named + GetTargetPathForAIExpansion,
17{
18 trace!("process_batch_output_and_errors => start.");
19
20 if let Some(output_data) = &batch_execution_result.outputs() {
22 info!("processing batch output data of len {}", output_data.len());
23 process_output_data::<T>(output_data, workspace, expected_content_type).await?;
25 }
26
27 if let Some(error_data) = &batch_execution_result.errors() {
29 info!("processing batch error data of len {}", error_data.len());
30 process_error_data(error_data).await?;
31 }
32
33 Ok(())
34}
35
36#[cfg(test)]
37mod process_batch_output_and_errors_tests {
38 use super::*;
39 use std::fs;
40 use tokio::runtime::Runtime;
41
42 #[derive(Debug, Clone, Deserialize, Serialize, NamedItem)]
43 pub struct BatchOutputErrorMockItem {
44 pub name: String,
45 }
46
47 #[traced_test]
48 async fn test_process_batch_output_and_errors() {
49
50 let workspace: Arc<dyn BatchWorkspaceInterface> = BatchWorkspace::new_temp().await.unwrap();
51
52 let success_msg = BatchMessageBuilder::default()
54 .role(MessageRole::Assistant)
55 .content(
56 BatchMessageContentBuilder::default()
57 .content("{\"name\":\"batch_out_item\"}".to_string())
58 .build()
59 .unwrap(),
60 )
61 .build()
62 .unwrap();
63
64 let success_choice = BatchChoiceBuilder::default()
65 .index(0_u32)
66 .finish_reason(FinishReason::Stop)
67 .logprobs(None)
68 .message(success_msg)
69 .build()
70 .unwrap();
71
72 let success_body = BatchSuccessResponseBodyBuilder::default()
73 .id("just-an-id".to_string())
74 .object("chat.completion".to_string())
75 .created(0_u64)
76 .model("test-model".to_string())
77 .choices(vec![success_choice])
78 .usage(BatchUsage::mock())
79 .build()
80 .unwrap();
81
82 let success_content = BatchResponseContentBuilder::default()
83 .status_code(200_u16)
84 .request_id(ResponseRequestId::new("resp_req_ok_1"))
85 .body(BatchResponseBody::Success(success_body))
86 .build()
87 .unwrap();
88
89 let success_record = BatchResponseRecordBuilder::default()
90 .id(BatchRequestId::new("batch_req_ok_1"))
91 .custom_id(CustomRequestId::new("ok_1"))
92 .response(success_content)
93 .build()
94 .unwrap();
95
96 let error_details = BatchErrorDetailsBuilder::default()
98 .error_type(ErrorType::Unknown("999".to_string()))
99 .message("some test error".to_string())
100 .build()
101 .unwrap();
102
103 let error_body = BatchErrorResponseBodyBuilder::default()
104 .error(error_details)
105 .build()
106 .unwrap();
107
108 let error_content = BatchResponseContentBuilder::default()
109 .status_code(400_u16)
110 .request_id(ResponseRequestId::new("resp_req_err_1"))
111 .body(BatchResponseBody::Error(error_body))
112 .build()
113 .unwrap();
114
115 let error_record = BatchResponseRecordBuilder::default()
116 .id(BatchRequestId::new("batch_req_err_1"))
117 .custom_id(CustomRequestId::new("err_1"))
118 .response(error_content)
119 .build()
120 .unwrap();
121
122 let out_data = BatchOutputData::new(vec![success_record]);
124 let err_data = BatchErrorData::new(vec![error_record]);
125 let batch_result = BatchExecutionResultBuilder::default()
126 .outputs(Some(out_data))
127 .errors(Some(err_data))
128 .build()
129 .unwrap();
130
131 let result = process_batch_output_and_errors::<BatchOutputErrorMockItem>(
133 workspace.as_ref(),
134 &batch_result,
135 &ExpectedContentType::Json,
136 ).await;
137
138 assert!(
140 result.is_ok(),
141 "Should handle success & error records gracefully, returning Ok."
142 );
143 }
144}