@@ -839,3 +839,205 @@ func (provider *GeminiProvider) BatchResults(ctx context.Context, key schemas.Ke
839839 },
840840 }, nil
841841}
842+
843+ // ==================== SDK RESPONSE CONVERTERS ====================
844+ // These functions convert Bifrost batch responses to Google GenAI SDK format.
845+
846+ // ToGeminiJobState converts Bifrost batch status to Gemini SDK job state.
847+ func ToGeminiJobState (status schemas.BatchStatus ) string {
848+ switch status {
849+ case schemas .BatchStatusValidating :
850+ return GeminiJobStatePending
851+ case schemas .BatchStatusInProgress :
852+ return GeminiJobStateRunning
853+ case schemas .BatchStatusFinalizing :
854+ return GeminiJobStateRunning
855+ case schemas .BatchStatusCompleted :
856+ return GeminiJobStateSucceeded
857+ case schemas .BatchStatusFailed :
858+ return GeminiJobStateFailed
859+ case schemas .BatchStatusCancelling :
860+ return GeminiJobStateCancelling
861+ case schemas .BatchStatusCancelled :
862+ return GeminiJobStateCancelled
863+ case schemas .BatchStatusExpired :
864+ return GeminiJobStateFailed
865+ default :
866+ return GeminiJobStatePending
867+ }
868+ }
869+
870+ // ToGeminiBatchJobResponse converts a BifrostBatchCreateResponse to Gemini SDK format.
871+ func ToGeminiBatchJobResponse (resp * schemas.BifrostBatchCreateResponse ) * GeminiBatchJobResponseSDK {
872+ if resp == nil {
873+ return nil
874+ }
875+
876+ result := & GeminiBatchJobResponseSDK {
877+ Name : resp .ID ,
878+ State : ToGeminiJobState (resp .Status ),
879+ }
880+
881+ // Add metadata if available
882+ if resp .CreatedAt > 0 {
883+ result .Metadata = & GeminiBatchMetadata {
884+ Name : resp .ID ,
885+ State : ToGeminiJobState (resp .Status ),
886+ CreateTime : time .Unix (resp .CreatedAt , 0 ).Format (time .RFC3339 ),
887+ BatchStats : & GeminiBatchStats {
888+ RequestCount : resp .RequestCounts .Total ,
889+ PendingRequestCount : resp .RequestCounts .Total - resp .RequestCounts .Completed ,
890+ SuccessfulRequestCount : resp .RequestCounts .Completed - resp .RequestCounts .Failed ,
891+ },
892+ }
893+ }
894+
895+ return result
896+ }
897+
898+ // ToGeminiBatchRetrieveResponse converts a BifrostBatchRetrieveResponse to Gemini SDK format.
899+ func ToGeminiBatchRetrieveResponse (resp * schemas.BifrostBatchRetrieveResponse ) * GeminiBatchJobResponseSDK {
900+ if resp == nil {
901+ return nil
902+ }
903+
904+ result := & GeminiBatchJobResponseSDK {
905+ Name : resp .ID ,
906+ State : ToGeminiJobState (resp .Status ),
907+ }
908+
909+ // Add metadata
910+ result .Metadata = & GeminiBatchMetadata {
911+ Name : resp .ID ,
912+ State : ToGeminiJobState (resp .Status ),
913+ CreateTime : time .Unix (resp .CreatedAt , 0 ).Format (time .RFC3339 ),
914+ BatchStats : & GeminiBatchStats {
915+ RequestCount : resp .RequestCounts .Total ,
916+ PendingRequestCount : resp .RequestCounts .Total - resp .RequestCounts .Completed ,
917+ SuccessfulRequestCount : resp .RequestCounts .Completed - resp .RequestCounts .Failed ,
918+ },
919+ }
920+
921+ if resp .CompletedAt != nil {
922+ result .Metadata .EndTime = time .Unix (* resp .CompletedAt , 0 ).Format (time .RFC3339 )
923+ }
924+
925+ // Add output file info if available
926+ if resp .OutputFileID != nil {
927+ result .Dest = & GeminiBatchDest {
928+ FileName : * resp .OutputFileID ,
929+ }
930+ }
931+
932+ return result
933+ }
934+
935+ // ToGeminiBatchListResponse converts a BifrostBatchListResponse to Gemini SDK format.
936+ func ToGeminiBatchListResponse (resp * schemas.BifrostBatchListResponse ) * GeminiBatchListResponseSDK {
937+ if resp == nil {
938+ return nil
939+ }
940+
941+ jobs := make ([]GeminiBatchJobResponseSDK , 0 , len (resp .Data ))
942+ for _ , batch := range resp .Data {
943+ job := GeminiBatchJobResponseSDK {
944+ Name : batch .ID ,
945+ State : ToGeminiJobState (batch .Status ),
946+ }
947+
948+ // Add metadata
949+ job .Metadata = & GeminiBatchMetadata {
950+ Name : batch .ID ,
951+ State : ToGeminiJobState (batch .Status ),
952+ CreateTime : time .Unix (batch .CreatedAt , 0 ).Format (time .RFC3339 ),
953+ BatchStats : & GeminiBatchStats {
954+ RequestCount : batch .RequestCounts .Total ,
955+ PendingRequestCount : batch .RequestCounts .Total - batch .RequestCounts .Completed ,
956+ SuccessfulRequestCount : batch .RequestCounts .Completed - batch .RequestCounts .Failed ,
957+ },
958+ }
959+
960+ jobs = append (jobs , job )
961+ }
962+
963+ result := & GeminiBatchListResponseSDK {
964+ BatchJobs : jobs ,
965+ }
966+
967+ if resp .NextCursor != nil {
968+ result .NextPageToken = * resp .NextCursor
969+ }
970+
971+ return result
972+ }
973+
974+ // ToGeminiBatchCancelResponse converts a BifrostBatchCancelResponse to Gemini SDK format.
975+ func ToGeminiBatchCancelResponse (resp * schemas.BifrostBatchCancelResponse ) * GeminiBatchJobResponseSDK {
976+ if resp == nil {
977+ return nil
978+ }
979+
980+ return & GeminiBatchJobResponseSDK {
981+ Name : resp .ID ,
982+ State : ToGeminiJobState (resp .Status ),
983+ }
984+ }
985+
986+ // BatchDelete deletes a batch job for Gemini.
987+ func (provider * GeminiProvider ) BatchDelete (ctx context.Context , key schemas.Key , request * schemas.BifrostBatchDeleteRequest ) (* schemas.BifrostBatchDeleteResponse , * schemas.BifrostError ) {
988+ if err := providerUtils .CheckOperationAllowed (schemas .Gemini , provider .customProviderConfig , schemas .BatchDeleteRequest ); err != nil {
989+ return nil , err
990+ }
991+
992+ providerName := provider .GetProviderKey ()
993+
994+ if request .BatchID == "" {
995+ return nil , providerUtils .NewBifrostOperationError ("batch_id is required" , nil , providerName )
996+ }
997+
998+ // Create HTTP request
999+ req := fasthttp .AcquireRequest ()
1000+ resp := fasthttp .AcquireResponse ()
1001+ defer fasthttp .ReleaseRequest (req )
1002+ defer fasthttp .ReleaseResponse (resp )
1003+
1004+ // Build URL for delete operation
1005+ batchID := request .BatchID
1006+ var url string
1007+ if strings .HasPrefix (batchID , "batches/" ) {
1008+ url = fmt .Sprintf ("%s/%s" , provider .networkConfig .BaseURL , batchID )
1009+ } else {
1010+ url = fmt .Sprintf ("%s/batches/%s" , provider .networkConfig .BaseURL , batchID )
1011+ }
1012+
1013+ provider .logger .Debug ("gemini batch delete url: " + url )
1014+ providerUtils .SetExtraHeaders (ctx , req , provider .networkConfig .ExtraHeaders , nil )
1015+ req .SetRequestURI (url )
1016+ req .Header .SetMethod (http .MethodDelete )
1017+ if key .Value != "" {
1018+ req .Header .Set ("x-goog-api-key" , key .Value )
1019+ }
1020+ req .Header .SetContentType ("application/json" )
1021+
1022+ // Make request
1023+ latency , bifrostErr := providerUtils .MakeRequestWithContext (ctx , provider .client , req , resp )
1024+ if bifrostErr != nil {
1025+ return nil , bifrostErr
1026+ }
1027+
1028+ // Handle response
1029+ if resp .StatusCode () != fasthttp .StatusOK && resp .StatusCode () != fasthttp .StatusNoContent {
1030+ return nil , parseGeminiError (providerName , resp )
1031+ }
1032+
1033+ return & schemas.BifrostBatchDeleteResponse {
1034+ ID : request .BatchID ,
1035+ Object : "batch" ,
1036+ Deleted : true ,
1037+ ExtraFields : schemas.BifrostResponseExtraFields {
1038+ RequestType : schemas .BatchDeleteRequest ,
1039+ Provider : providerName ,
1040+ Latency : latency .Milliseconds (),
1041+ },
1042+ }, nil
1043+ }
0 commit comments