classLMStudio(CustomLLM):base_url:str=Field(default="http://localhost:1234/v1",description="Base url the model is hosted under.",)context_window:int=Field(default=DEFAULT_CONTEXT_WINDOW,description="The maximum number of context tokens for the model.",gt=0,)model_name:str=Field(description="The model to use.")request_timeout:float=Field(default=DEFAULT_REQUEST_TIMEOUT,description="The timeout for making http request in seconds to LM Studio API server.",)num_output:int=Field(default=DEFAULT_NUM_OUTPUTS,description=LLMMetadata.model_fields["num_output"].description,)is_chat_model:bool=Field(default=True,description=("LM Studio API supports chat."+LLMMetadata.model_fields["is_chat_model"].description),)temperature:float=Field(default=DEFAULT_TEMPERATURE,description=("The temperature to use for sampling."),ge=0.0,le=1.0,)timeout:float=Field(default=120,description=("The timeout to use in seconds."),ge=0)additional_kwargs:Dict[str,Any]=Field(default_factory=dict,description=("Additional kwargs to pass to the model."))def_create_payload_from_messages(self,messages:Sequence[ChatMessage],**kwargs:Any)->Dict[str,Any]:return{"model":self.model_name,"messages":[{"role":message.role.value,"content":message.content,**(message.additional_kwargsifmessage.additional_kwargsisnotNoneelse{}),}formessageinmessages],"options":self._model_kwargs,"stream":False,**kwargs,}def_create_chat_response_from_http_response(self,response:httpx.Response)->ChatResponse:raw=response.json()message=raw["choices"][0]["message"]returnChatResponse(message=ChatMessage(content=message.get("content"),role=MessageRole(message.get("role")),additional_kwargs=get_additional_kwargs(message,("content","role")),),raw=raw,additional_kwargs=get_additional_kwargs(raw,("choices",)),)@llm_chat_callback()defchat(self,messages:Sequence[ChatMessage],**kwargs:Any)->ChatResponse:payload=self._create_payload_from_messages(messages,**kwargs)withhttpx.Client(timeout=Timeout(self.request_timeout))asclient:response=client.post(url=f"{self.base_url}/chat/completions",json=payload,)response.raise_for_status()returnself._create_chat_response_from_http_response(response)@llm_chat_callback()asyncdefachat(self,messages:Sequence[ChatMessage],**kwargs:Any)->ChatResponse:payload=self._create_payload_from_messages(messages,**kwargs)asyncwithhttpx.AsyncClient(timeout=Timeout(self.request_timeout))asclient:response=awaitclient.post(url=f"{self.base_url}/chat/completions",json=payload,)response.raise_for_status()returnself._create_chat_response_from_http_response(response)@llm_completion_callback()defcomplete(self,prompt:str,formatted:bool=False,**kwargs:Any)->CompletionResponse:complete_fn=chat_to_completion_decorator(self.chat)returncomplete_fn(prompt,**kwargs)@llm_completion_callback()asyncdefacomplete(self,prompt:str,formatted:bool=False,**kwargs:Any)->CompletionResponse:acomplete_fn=achat_to_completion_decorator(self.achat)returnawaitacomplete_fn(prompt,**kwargs)@llm_chat_callback()defstream_chat(self,messages:Sequence[ChatMessage],**kwargs:Any)->ChatResponseGen:payload=self._create_payload_from_messages(messages,stream=True,**kwargs)withhttpx.Client(timeout=Timeout(self.request_timeout))asclient:withclient.stream(method="POST",url=f"{self.base_url}/chat/completions",json=payload,)asresponse:response.raise_for_status()text=""forlineinresponse.iter_lines():ifline:line=line.strip()ifisinstance(line,bytes):line=line.decode("utf-8")ifline.startswith("data: [DONE]"):break# Slice the line to remove the "data: " prefixchunk=json.loads(line[5:])delta=chunk["choices"][0].get("delta")role=delta.get("role")orMessageRole.ASSISTANTcontent_delta=delta.get("content")or""text+=content_deltayieldChatResponse(message=ChatMessage(content=text,role=MessageRole(role),additional_kwargs=get_additional_kwargs(chunk,("choices",)),),delta=content_delta,raw=chunk,additional_kwargs=get_additional_kwargs(chunk,("choices",)),)@llm_completion_callback()defstream_complete(self,prompt:str,formatted:bool=False,**kwargs:Any)->CompletionResponseGen:stream_complete_fn=stream_chat_to_completion_decorator(self.stream_chat)returnstream_complete_fn(prompt,**kwargs)@llm_completion_callback()asyncdefastream_complete(self,prompt:str,formatted:bool=False,**kwargs:Any)->CompletionResponseAsyncGen:astream_complete_fn=astream_chat_to_completion_decorator(self.astream_chat)returnawaitastream_complete_fn(prompt,**kwargs)@propertydefmetadata(self)->LLMMetadata:"""LLM metadata."""returnLLMMetadata(context_window=self.context_window,num_output=self.num_output,model_name=self.model_name,is_chat_model=self.is_chat_model,)@propertydef_model_kwargs(self)->Dict[str,Any]:base_kwargs={"temperature":self.temperature,"num_ctx":self.context_window,}return{**base_kwargs,**self.additional_kwargs,}