
    6i,                        d Z ddlmZ ddlmZmZ ddlZddlZddlZddl	m
Z
mZmZmZmZ ddlmZ ddlmZ  G d	 d
ee         Zy)z
Batch processor for unified batch processing across providers.

This module contains the BatchProcessor class that provides a unified interface
for batch processing across different LLM providers.
    )annotations)AnyGenericN   )BatchResultBatchSuccess
BatchErrorBatchJobInfoT)BatchRequest)get_providerc                      e Zd ZdZddZ	 	 	 d	 	 	 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 ddZddZddZdddZ		 d	 	 	 	 	 dd	Z
dd
ZddZddZddZy)BatchProcessorz7Unified batch processor that works across all providersc                    || _         || _        	 |j                  dd      \  | _        | _        t        | j                        | _        y # t
        $ r}t        d      |d }~ww xY w)N/r   ziModel string must be in format "provider/model-name" (e.g. "openai/gpt-4" or "anthropic/claude-3-sonnet"))modelresponse_modelsplitprovider_name
model_name
ValueErrorr   provider)selfr   r   errs       e/root/.openclaw/workspace/visionaryfx/venv/lib/python3.12/site-packages/instructor/batch/processor.py__init__zBatchProcessor.__init__   sn    
,	27++c12E/D %T%7%78  	G 	s   A
 
	A$AA$Nc           	        |t         j                  j                  |      rt        j                  |       g }t	        |      D ]g  \  }}t        | j                     d| || j                  | j                  ||      }|j                  || j                         |j                  |       i t        d| dt        |       d       |S t        j                         }	g }t	        |      D ]g  \  }}t        | j                     d| || j                  | j                  ||      }|j                  |	| j                         |j                  |       i t        dt        |       d       |	j                  d       |	S )a  Create batch file from list of message conversations

        Args:
            messages_list: List of message conversations, each as a list of message dicts
            file_path: Path to save the batch request file. If None, returns BytesIO buffer
            max_tokens: Maximum tokens per request
            temperature: Temperature for generation

        Returns:
            The file path where the batch was saved, or BytesIO buffer if file_path is None
        zrequest-)	custom_idmessagesr   r   
max_tokenstemperaturezCreated batch file z with z	 requestszCreated batch buffer with r   )ospathexistsremove	enumerater   r   r   save_to_filer   appendprintlenioBytesIOseek)
r   messages_list	file_pathr    r!   batch_requestsir   batch_requestbuffers
             r   create_batch_from_messagesz)BatchProcessor.create_batch_from_messages%   sw   $  ww~~i(		)$N(7 
58 ,T-@-@ A (n%#'#6#6//) +! **9d6H6HI%%m4
5 '	{&^9L8MYWX ZZ\FN(7 
58 ,T-@-@ A (n%#'#6#6//) +! **643E3EF%%m4
5 .s>/B.C9MNKKNM    c                L    |ddi} | j                   j                  |fd|i|S )a  Submit batch job to the provider and return job ID

        Args:
            file_path_or_buffer: Path to the batch request file or BytesIO buffer
            metadata: Optional metadata to attach to the batch job
            **kwargs: Additional provider-specific arguments
        descriptionzInstructor batch jobmetadata)r   submit_batch)r   file_path_or_bufferr8   kwargss       r   r9   zBatchProcessor.submit_batch^   sA     %'=>H)t}}))
*2
6<
 	
r5   c                8    | j                   j                  |      S )z&Get batch job status from the provider)r   
get_statusr   batch_ids     r   get_batch_statuszBatchProcessor.get_batch_statusr   s    }}''11r5   c                Z    | j                   j                  |      }| j                  |      S )z2Retrieve and parse batch results from the provider)r   retrieve_resultsparse_results)r   r?   results_contents      r   rB   zBatchProcessor.retrieve_resultsv   s'    --88B!!/22r5   c                8    | j                   j                  |      S )zList batch jobs for the current provider

        Args:
            limit: Maximum number of batch jobs to return

        Returns:
            List of BatchJobInfo objects with normalized batch information
        )r   list_batches)r   limits     r   rF   zBatchProcessor.list_batches{   s     }}))%00r5   c                d    | j                  |      }|| j                  j                  ||       |S )a  Get batch results, optionally saving raw results to a file

        Args:
            batch_id: The batch job ID
            file_path: Optional file path to save raw results. If provided,
                      raw results will be saved to this file. If not provided,
                      results are only kept in memory.

        Returns:
            List of BatchResult objects (BatchSuccess[T] or BatchError)
        )rB   r   download_results)r   r?   r/   rD   s       r   get_resultszBatchProcessor.get_results   s6     //9  MM**8Y?r5   c                8    | j                   j                  |      S )zCancel a batch job

        Args:
            batch_id: The batch job ID to cancel

        Returns:
            Dict containing the cancelled batch information
        )r   cancel_batchr>   s     r   rL   zBatchProcessor.cancel_batch        }}))(33r5   c                8    | j                   j                  |      S )zDelete a batch job (only available for completed batches)

        Args:
            batch_id: The batch job ID to delete

        Returns:
            Dict containing the deletion confirmation
        )r   delete_batchr>   s     r   rO   zBatchProcessor.delete_batch   rM   r5   c           
        g }|j                         j                  d      }|D ]5  }|j                         s	 t        j                  |      }|j	                  dd      }| j                  |      }|r9	  | j                  di |}t        t           ||      }	|j                  |	       nd
}d}| j                  dk(  rzd|v rv|d   }|j	                  d      dk(  r]|j	                  di       }t        |t              r.d|v r*|d   }|j	                  dd      }|j	                  dd      }nt!        |      }d}t        ||||      }|j                  |       8 |S # t        $ rD}
t        |dd| j                  j                   d|
 |      }|j                  |       Y d	}
~
Md	}
~
ww xY w# t        $ r0}
t        ddd|
 d|i      }|j                  |       Y d	}
~
d	}
~
ww xY w)zWParse batch results from content string into Maybe-like results with custom_id tracking
r   unknown)r   resultparsing_errorzFailed to parse into z: )r   
error_typeerror_messageraw_dataNzUnknown errorextraction_error	anthropicrS   typeerrormessagezUnknown Anthropic erroranthropic_errorjson_parse_errorzFailed to parse JSON: raw_line )stripr   jsonloadsget_extract_from_responser   r   r   r(   	Exceptionr	   __name__r   
isinstancedictstr)r   rD   resultslineslinedatar   extracted_datarS   batch_resulteerror_resultrV   rU   
error_infoerror_detailss                   r   rC   zBatchProcessor.parse_results   s   %'%%'--d3 =	-D::<9-zz$' HH[)<	!%!<!<T!B!5!4!4!4!F~!F'3A&/(  |4 %4M!3J))[8X=M!%h!::f-8)/GR)@J)*d;:@U0:70C0=0A0A$-/H1" .;->->$*,=."
 14J->
#-"+#-&3!%	$L NN<0i=	-~ ] % 5'1&/'6,A$BUBUB^B^A__abcad*e%3	(  |445J  -)'1$:1#">($/	  |,,-sB   :F/57E,B.F/	F,(:F'"F/'F,,F//	G(8%G##G(c                   	 | j                   dk(  r)|d   d   d   d   d   d   }t        j                  |      S | j                   dk(  rd	|vry
|d	   }|j                  d      dk(  ry
|j                  d      dk(  rd|v r|d   d   }t	        |t
              rt        |      dkD  rt|D ]*  }|j                  d      dk(  s|j                  di       c S  |D ]@  }|j                  d      dk(  s|j                  dd      }	 t        j                  |      c S  y
	 y
# t        j                  $ r Y [w xY w# t        $ r Y y
w xY w)z>Extract structured data from provider-specific response formatopenairesponsebodychoicesr   r\   contentrY   rS   NrZ   r[   	succeededtool_useinputtext )	r   rb   rc   rd   rh   listr*   JSONDecodeErrorrf   )r   rn   rz   rS   itemr~   s         r   re   z%BatchProcessor._extract_from_response   sq   '	!!X-z*629=a@KIVzz'**##{24'h ::f%0 ::f%4f9L$Y/	:G!'40S\A5E$+ =D#xx/:='+xx'< <=
 %, -D#xx/69'+xx';!-+/::d+;$;	- = 3F  (,';'; !-$,!-
  		s_   7D6 D6 D6 (AD6  D6 D6 /D6 DD6 D6 D30D6 2D33D6 6	EE)r   rj   r   ztype[T])Ni  g?)
r.   zlist[list[dict[str, Any]]]r/   
str | Noner    z
int | Noner!   zfloat | Nonereturnstr | io.BytesIO)N)r:   r   r8   dict[str, Any] | Noner   rj   )r?   rj   r   dict[str, Any])r?   rj   r   list[BatchResult])
   )rG   intr   zlist[BatchJobInfo])r?   rj   r/   r   r   r   )rD   rj   r   r   )rn   r   r   r   )rg   
__module____qualname____doc__r   r4   r9   r@   rB   rF   rJ   rL   rO   rC   re   r`   r5   r   r   r      s    A9& !%!%$'717 7 	7
 "7 
7x +/
-
 (

 

(23
	1 6:(2	.	4	4DL+r5   r   )r   
__future__r   typingr   r   rb   r"   r+   modelsr   r   r	   r
   r   requestr   	providersr   r   r`   r5   r   <module>r      s9    #   	 	 J J ! #RWQZ Rr5   