
    9|hk:                       d dl mZ d dlZd dlZd dlmZ d dlmZmZm	Z	m
Z
mZmZmZmZ d dlZd dlmZ d dlmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ d dlmZ d dlmZ d dl m!Z! d dl"m#Z# erd dl$m%Z% d dl&m'Z' ddZ(ddZ)ddZ*	 	 	 	 ddZ+ G d de      Z, eddd      	 	 	 	 	 	 	 d 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d!d       Z-y)"    )annotationsN)defaultdict)TYPE_CHECKINGAnyCallableDictListOptionalTupleUnion)
deprecated)CallbackManagerForChainRun)BaseLanguageModel)JsonOutputFunctionsParser)BasePromptTemplateChatPromptTemplate)get_colored_text)Response)Chain)LLMChain)SequentialChainOpenAPISpec)	Parameterc                R    t        | dd       }t        | dd       }|r|xs |S |xs |S )Nsummarydescription)getattr)oprefer_shortr   r   s       h/var/www/html/test/engine/venv/lib/python3.12/site-packages/langchain/chains/openai_functions/openapi.py_get_descriptionr"      s7    aD)G!]D1K%+%!'!    c           	        t        j                  d|       }i }|D ]J  }|j                  d      j                  d      }||   }t	        |t
              rj|d   dk(  r!|d   dk(  rdnd}d|j                  |      z   }n|d   dk(  r'|d   dk(  r| d	nd}| d	|j                  |      z   }ndj                  |      }nt	        |t              rr|d   dk(  rd	nd}	|j                         D 
cg c]  \  }
}|	j                  |
|f       }}
}|d   dk(  rd}d}n|d   dk(  rd}d}nd}d
}||j                  |      z  }n!|d   dk(  rd| }n|d   dk(  r	d| d	| }n|}|||<   M  | j                  di |S c c}}
w )Nz{(.*?)}z.;*r   .,;=  )
refindalllstriprstrip
isinstancelistjoindictitemsformat)urlpath_paramsexpected_path_param
new_paramsparamclean_paramvalsepnew_valkv_sepkvkv_strss                r!   _format_urlrD   "   s   **Z5J$  $ll4(//4+&c4 Qx3"2Y#-c3-qS+09+;Q'(M+chhsm;((3-T"!"I,S#F7:yy{Ctq!v{{Aq6*CGCQx3qSsxx((GQx3cU)qSk]!C51#
5A $B 3::#
##' Ds   -E;c                   i }g }| D ]  }|j                   r|j                  |j                         }nAt        |j                  j	                               d   j
                  }|j                  |      }|j                  r|j                  s|j                  |_        t        j                  |j                  d            ||j                  <   |j                  s|j                  |j                          d||dS )Nr   Texclude_noneobject)type
propertiesrequired)param_schema
get_schemar2   contentvaluesmedia_type_schemar   jsonloadsnamerK   append)paramsspecrJ   rK   pschemarP   s          r!   _openapi_params_to_json_schemarY   I   s    JH 
$>>__Q^^4F $QYY%5%5%7 8 ; M M__%67F==!3!3!"F!ZZ(FG
166::OOAFF#
$ JHMMr#   c                   	 ddl m} | j                  sg d fS g }i | j                  D ]x  }| j	                  |      D ci c]  }|j
                  |j                  f| }}| j                  |      D ]+  }i }| j                  ||      }|j                         }	| j                  |      D ]  }
|
|	|
j
                  |
j                  f<    t        t              }|	j                         D ]  \  }}||d      j                  |        dddd	d
}|j                         D ]  \  }}||   st        ||   |       ||<    | j!                  |      }|r|j"                  ri }|j"                  j                         D ]U  \  }}|j$                  s| j'                  |j$                        }t)        j*                  |j)                  d            ||<   W t-        |      dk(  r.t        |j                               d   \  }}|dk(  rdnd}|||<   n,t-        |      dkD  rdt        |j/                               i|d<   |j1                  | ||      }|j2                  |j4                  d|dd}|j                  |       ||j6                  |j8                  z   d|d   <   . { 	 	 d	 	 	 	 	 	 	 	 	 	 	 dfd}||fS # t        $ r t        d      w xY wc c}w )a4  Convert a valid OpenAPI spec to the JSON Schema format expected for OpenAI
        functions.

    Args:
        spec: OpenAPI spec to convert.

    Returns:
        Tuple of the OpenAI functions JSON schema and a default function for executing
            a request based on the OpenAI function schema.
    r   )APIOperationzeCould not import langchain_community.tools. Please install it with `pip install langchain-community`.c                      y Nr,   r,   r#   r!   <lambda>z+openapi_spec_to_openai_fn.<locals>.<lambda>p   s    r#      rU   headerscookiesr8   )queryheadercookiepathTrF   zapplication/jsonrQ   dataanyOfrH   )rI   rJ   )rS   r   
parameters)methodr7   rS   c                ~   	|    d   }	|    d   }|j                  di       }t        ||      }d|v r.t        |d   t              rt	        j
                  |d         |d<   i ||}|d|v r|d   j                  |       n||d<   |d|v r|d   j                  |       n||d<   t        j                  ||fi |S )Nri   r7   r8   rf   r`   rU   )	poprD   r1   r4   rQ   dumpsupdaterequestsrequest)
rS   fn_argsr`   rU   kwargsri   r7   r8   _kwargs_name_to_call_maps
            r!   default_call_apiz3openapi_spec_to_openai_fn.<locals>.default_call_api   s     #4(2%e,kk-4#{+WGFOT!B"jj9GFO'W''G#	"))'2%,	"7"!((0$*!7w77r#   )NN)rS   strrp   r4   r`   Optional[dict]rU   rv   rq   r   returnr   )langchain_community.toolsr[   ImportErrorpathsget_parameters_for_pathrS   param_inget_methods_for_pathget_operationcopyget_parameters_for_operationr   r2   r5   rT   rY   get_request_body_for_operationrN   rP   rM   rQ   rR   lenrO   from_openapi_specoperation_idr   base_urlre   )rV   r[   	functionsre   rW   r8   ri   request_argsop	op_paramsr;   params_by_typename_locparam_loc_to_arg_name	param_locarg_namerequest_bodymedia_types
media_typemedia_type_objectrX   schema_dictkeyapi_opfnrt   rs   s                             @r!   openapi_spec_to_openai_fnr   Z   sW   
: ::<I

 6-1-I-I$-O
()QVVQZZ !#
 
 //5 2	FL##D&1B#((*I::2> @:?	5::u~~67@(.N(0 6!x{+22156 "##%	%! (='B'B'D #	8!),-K&y14.L*
  >>rBL 4 4 5A5I5I5O5O5Q 1J 1(::!%1B1T1T!U26**"KKTK:3J/ {#q(.2;3D3D3F.G.J+J$.2D$D&&C(3L%%),3T+:L:L:N5O+PL(!33D$GF++%11$".B R  4-bj)_2		6v #'!%	888  8 	8
 8 
84 &&&y  
H
 	


s   J>  K>Kc                  x    e Zd ZU dZded<   	 dZded<   	 dZded<   	 edd	       Zedd
       Z		 d	 	 	 	 	 ddZ
y)SimpleRequestChainz5Chain for making a simple request to an API endpoint.r   request_methodresponseru   
output_keyfunction	input_keyc                    | j                   gS r]   )r   selfs    r!   
input_keyszSimpleRequestChain.input_keys   s    r#   c                    | j                   gS r]   )r   r   s    r!   output_keyszSimpleRequestChain.output_keys   s      r#   Nc                `   |xs t        j                         }|| j                     j                  d      }|| j                     j                  d      }t	        |d      }t	        t        j                  |d      d      }d| d|z   }|j                  |       | j                  ||      }	|	j                  dk7  r9|	j                   d	|	j                   d
| dz   d|j                  dd       z   }
n	 |	j                         }
| j                  |
iS # t        $ r |	j                  }
Y %w xY w)z2Run the logic of this chain and return the output.rS   	argumentsgreen   )indentzCalling endpoint z with arguments:
   z: z
For  zCalled with args: rU   r+   )r   get_noop_managerr   rk   r   rQ   rl   on_textr   status_codereasonget	Exceptiontextr   )r   inputsrun_manager_run_managerrS   args_pretty_name_pretty_args_textapi_responser   s              r!   _callzSimpleRequestChain._call   s=    #S&@&Q&Q&Sdnn%))&1dnn%))+6'g6'

4(BGL#L>1CD|SU#!%!4!4T4!@##s*++,B|/B/B.CD4&"#&txx"'=&>?@ -',,. **  -',,-s   7D D-,D-)rw   z	List[str]r]   )r   Dict[str, Any]r   z$Optional[CallbackManagerForChainRun]rw   r   )__name__
__module____qualname____doc____annotations__r   r   propertyr   r   r   r,   r#   r!   r   r      su    ?/ J 3Is2    ! ! =A++ :+ 
	+r#   r   z0.2.13zThis function is deprecated and will be removed in langchain 1.0. See API reference for replacement: https://api.python.langchain.com/en/latest/chains/langchain.chains.openai_functions.openapi.get_openapi_chain.htmlz1.0)sincemessageremovalc           
     \   	 ddl m}	 t        | t              rP|	j
                  |	j                  |	j                  fD ]  }	  ||       }  n t        | t              rt        d|        t        |       \  }|st        d      |xs t        j                  d      }t        d||d|it        d	
      d|d|xs i }|xs t        fd|      }t!        d||g|j"                  dg|d|S # t        $ r}
t        d      |
d}
~
ww xY w# t        $ r}
|
d}
~
wt        $ r Y w xY w)a  Create a chain for querying an API from a OpenAPI spec.

    Note: this class is deprecated. See below for a replacement implementation.
        The benefits of this implementation are:

        - Uses LLM tool calling features to encourage properly-formatted API requests;
        - Includes async support.

        .. code-block:: python

            from typing import Any

            from langchain.chains.openai_functions.openapi import openapi_spec_to_openai_fn
            from langchain_community.utilities.openapi import OpenAPISpec
            from langchain_core.prompts import ChatPromptTemplate
            from langchain_openai import ChatOpenAI

            # Define API spec. Can be JSON or YAML
            api_spec = """
            {
            "openapi": "3.1.0",
            "info": {
                "title": "JSONPlaceholder API",
                "version": "1.0.0"
            },
            "servers": [
                {
                "url": "https://jsonplaceholder.typicode.com"
                }
            ],
            "paths": {
                "/posts": {
                "get": {
                    "summary": "Get posts",
                    "parameters": [
                    {
                        "name": "_limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                        "type": "integer",
                        "example": 2
                        },
                        "description": "Limit the number of results"
                    }
                    ]
                }
                }
            }
            }
            """

            parsed_spec = OpenAPISpec.from_text(api_spec)
            openai_fns, call_api_fn = openapi_spec_to_openai_fn(parsed_spec)
            tools = [
                {"type": "function", "function": fn}
                for fn in openai_fns
            ]

            prompt = ChatPromptTemplate.from_template(
                "Use the provided APIs to respond to this user query:\n\n{query}"
            )
            llm = ChatOpenAI(model="gpt-4o-mini", temperature=0).bind_tools(tools)

            def _execute_tool(message) -> Any:
                if tool_calls := message.tool_calls:
                    tool_call = message.tool_calls[0]
                    response = call_api_fn(name=tool_call["name"], fn_args=tool_call["args"])
                    response.raise_for_status()
                    return response.json()
                else:
                    return message.content

            chain = prompt | llm | _execute_tool

        .. code-block:: python

            response = chain.invoke({"query": "Get me top two posts."})

    Args:
        spec: OpenAPISpec or url/file/text string corresponding to one.
        llm: language model, should be an OpenAI function-calling model, e.g.
            `ChatOpenAI(model="gpt-3.5-turbo-0613")`.
        prompt: Main prompt template to use.
        request_chain: Chain for taking the functions output and executing the request.
    r   r   zqCould not import langchain_community.utilities.openapi. Please install it with `pip install langchain-community`.Nz!Unable to parse spec from source zkMust provide an LLM for this chain.For example,
from langchain_openai import ChatOpenAI
llm = ChatOpenAI()
z>Use the provided API's to respond to this user query:

{query}r   F)	args_onlyr   )llmprompt
llm_kwargsoutput_parserr   verbosec                     | |      S )N)r`   rU   r,   )rS   r   call_api_fnr`   rU   s     r!   r^   z#get_openapi_chain.<locals>.<lambda>  s    +$+
 r#   )r   r   r   )chainsinput_variablesoutput_variablesr   r,   )%langchain_community.utilities.openapir   ry   r1   ru   from_url	from_file	from_textr   
ValueErrorr   r   from_templater   r   r   r   r   )rV   r   r   request_chainllm_chain_kwargsr   r`   rU   rq   r   e
conversion
openai_fns	llm_chainr   s         ``      @r!   get_openapi_chainr      s   TE $  !!!!
 	J
!$'	 dC @GHH7=J#
 	

  )77JF  ,/%@ !rI " %7
 	&M  =)!,,$	
  [  H
 	   s5   C4 D4	D=D		D	D+DD+*D+)r   r   r    boolrw   zOptional[str])r7   ru   r8   r4   rw   ru   )rU   zList[Parameter]rV   r   rw   r4   )rV   r   rw   z%Tuple[List[Dict[str, Any]], Callable])NNNNFNN)rV   zUnion[OpenAPISpec, str]r   zOptional[BaseLanguageModel]r   zOptional[BasePromptTemplate]r   zOptional[Chain]r   Optional[Dict]r   r   r`   r   rU   r   rq   r   rw   r   ).
__future__r   rQ   r-   collectionsr   typingr   r   r   r   r	   r
   r   r   rn   langchain_core._apir   langchain_core.callbacksr   langchain_core.language_modelsr   .langchain_core.output_parsers.openai_functionsr   langchain_core.promptsr   r   langchain_core.utils.inputr   r   langchain.chains.baser   langchain.chains.llmr   langchain.chains.sequentialr   r   r   openapi_pydanticr   r"   rD   rY   r   r   r   r,   r#   r!   <module>r      s%   "  	 # S S S  * ? < T I 7  ' ) 7A*"$$NN"k'
k'*k'\++ ++\ 
	}  (,+/%)'+"!V
!V	$V )V #	V
 %V V V V V VVr#   