# -*- coding: utf-8 -*-"""Parser for model response."""importjsonfromtypingimportOptional,Sequence,Any,Generator,Union,Tuplefrom..messageimportToolUseBlockfrom..utils.commonimport_is_json_serializable
[docs]classModelResponse:"""Encapsulation of data returned by the model. The main purpose of this class is to align the return formats of different models and act as a bridge between models and agents. """def__init__(self,text:Optional[str]=None,embedding:Optional[Sequence]=None,image_urls:Optional[Sequence[str]]=None,raw:Any=None,parsed:Optional[Any]=None,stream:Optional[Generator[str,None,None]]=None,tool_calls:Optional[list[ToolUseBlock]]=None,)->None:"""Initialize the model response. Args: text (`str`, optional): The text field. embedding (`Sequence`, optional): The embedding returned by the model. image_urls (`Sequence[str]`, optional): The image URLs returned by the model. raw (`Any`, optional): The raw data returned by the model. parsed (`Any`, optional): The parsed data returned by the model. stream (`Generator`, optional): The stream data returned by the model. tool_calls (`Optional[list[dict]]`, defaults to `None`): The tool calls made by the model. """self._text=textself.embedding=embeddingself.image_urls=image_urlsself.raw=rawself.parsed=parsedself._stream=streamself.tool_calls=tool_callsself._is_stream_exhausted=False@propertydeftext(self)->Union[str,None]:"""Return the text field. If the stream field is available, the text field will be updated accordingly."""ifself._textisNone:ifself.streamisnotNone:for_,chunkinself.stream:self._text=chunkreturnself._text@text.setterdeftext(self,value:str)->None:"""Set the text field."""self._text=value@propertydefstream(self)->Union[None,Generator[Tuple[bool,str],None,None]]:"""Return the stream generator if it exists."""ifself._streamisNone:returnself._streamelse:returnself._stream_generator_wrapper()@propertydefis_stream_exhausted(self)->bool:"""Whether the stream has been processed already."""returnself._is_stream_exhausteddef_stream_generator_wrapper(self,)->Generator[Tuple[bool,str],None,None]:"""During processing the stream generator, the text field is updated accordingly."""ifself._is_stream_exhausted:raiseRuntimeError("The stream has been processed already. Try to obtain the ""result from the text field.",)# These two lines are used to avoid mypy checking errorifself._streamisNone:returntry:last_text=next(self._stream)fortextinself._stream:self._text=last_textyieldFalse,last_textlast_text=textself._text=last_textyieldTrue,last_textreturnexceptStopIteration:returndef__str__(self)->str:if_is_json_serializable(self.raw):raw=self.rawelse:raw=str(self.raw)serialized_fields={"text":self.text,"embedding":self.embedding,"image_urls":self.image_urls,"parsed":self.parsed,"raw":raw,}returnjson.dumps(serialized_fields,indent=4,ensure_ascii=False)