o
    iH                     @  s6  d dl mZ d dlZd dlmZmZ d dlmZ d dl	m	Z	 d dl
mZmZmZmZmZ d dlmZmZmZ d dlmZmZmZmZ d d	lmZ d
dlmZmZmZmZ m!Z" d
dl#m$Z$ d
dl%m&Z& erjd
dl'm(Z( ej)ddG dd dee&e$f Z*ej)G dd dee$ Z+ej)ddG dd dee$ Z,dS )    )annotationsN)AsyncIteratorSequence)deepcopy)datetime)TYPE_CHECKINGAnyGenericLiteraloverload)BaseNodeEndGraphRunContext)	EndMarkerGraphRun	GraphTaskJoinItem)NodeStep   )_agent_graph_utils
exceptionsmessagesusage)OutputDataT)
AgentDepsT)FinalResultF)reprc                   @  s   e Zd ZU dZded< ed=dd	Zed>dd	Zddd?dd	Zed@ddZedAddZ	edBddZ
dCddZdddDd d!ZdCd"d#ZdEd$d%ZdFd'd(ZdAd)d*ZdGd-d.ZdHd2d3ZdId4d5ZdJd7d8Zed>d9d:Zd>d;d<ZdS )KAgentRuna  A stateful, async-iterable run of an [`Agent`][pydantic_ai.agent.Agent].

    You generally obtain an `AgentRun` instance by calling `async with my_agent.iter(...) as agent_run:`.

    Once you have an instance, you can use it to iterate through the run's nodes as they execute. When an
    [`End`][pydantic_graph.nodes.End] is reached, the run finishes and [`result`][pydantic_ai.agent.AgentRun.result]
    becomes available.

    Example:
    ```python
    from pydantic_ai import Agent

    agent = Agent('openai:gpt-4o')

    async def main():
        nodes = []
        # Iterate through the run, recording each node along the way:
        async with agent.iter('What is the capital of France?') as agent_run:
            async for node in agent_run:
                nodes.append(node)
        print(nodes)
        '''
        [
            UserPromptNode(
                user_prompt='What is the capital of France?',
                instructions_functions=[],
                system_prompts=(),
                system_prompt_functions=[],
                system_prompt_dynamic_functions={},
            ),
            ModelRequestNode(
                request=ModelRequest(
                    parts=[
                        UserPromptPart(
                            content='What is the capital of France?',
                            timestamp=datetime.datetime(...),
                        )
                    ],
                    run_id='...',
                )
            ),
            CallToolsNode(
                model_response=ModelResponse(
                    parts=[TextPart(content='The capital of France is Paris.')],
                    usage=RequestUsage(input_tokens=56, output_tokens=7),
                    model_name='gpt-4o',
                    timestamp=datetime.datetime(...),
                    run_id='...',
                )
            ),
            End(data=FinalResult(output='The capital of France is Paris.')),
        ]
        '''
        print(agent_run.result.output)
        #> The capital of France is Paris.
    ```

    You can also manually drive the iteration using the [`next`][pydantic_ai.agent.AgentRun.next] method for
    more granular control.
    znGraphRun[_agent_graph.GraphAgentState, _agent_graph.GraphAgentDeps[AgentDepsT, Any], FinalResult[OutputDataT]]
_graph_runrequiredLiteral[False]return
str | Nonec                C     d S N selfr    r&   r&   U/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/pydantic_ai/run.py_traceparent^      zAgentRun._traceparentstrc                 C  r$   r%   r&   r(   r&   r&   r)   r*   `   r+   Tr    boolc                C  s&   | j jdd}|d u r|rtd|S )NFr.   &No span was created for this agent run)r   r*   AttributeError)r(   r    traceparentr&   r&   r)   r*   b   s   [GraphRunContext[_agent_graph.GraphAgentState, _agent_graph.GraphAgentDeps[AgentDepsT, Any]]c                 C  s(   t tjtjttf f | jj| jjdS )z%The current context of the agent run.)statedeps)	r   r   GraphAgentStateGraphAgentDepsr   r   r   r4   r5   r-   r&   r&   r)   ctxh   s   zAgentRun.ctxO_agent_graph.AgentNode[AgentDepsT, OutputDataT] | End[FinalResult[OutputDataT]]c                 C  s   | j j}| |S )zThe next node that will be run in the agent graph.

        This is the next node that will be used during async iteration, or if a node is not passed to `self.next(...)`.
        )r   	next_task_task_to_noder(   taskr&   r&   r)   	next_nodeo   s   
zAgentRun.next_node"AgentRunResult[OutputDataT] | Nonec                 C  s:   | j j}|du r
dS t|j|j| j j| j jj| jddS )zThe final result of the run if it has ended, otherwise `None`.

        Once the run returns an [`End`][pydantic_graph.nodes.End] node, `result` is populated
        with an [`AgentRunResult`][pydantic_ai.agent.AgentRunResult].
        NFr.   )r   outputAgentRunResult	tool_namer4   r5   new_message_indexr*   )r(   graph_run_outputr&   r&   r)   resultz   s   
zAgentRun.resultlist[_messages.ModelMessage]c                 C  
   | j jjS )z`Return all messages for the run so far.

        Messages from older runs are included.
        )r8   r4   message_historyr-   r&   r&   r)   all_messages   s   
zAgentRun.all_messagesNoutput_tool_return_contentrK   bytesc                C     t j|  S )zReturn all messages from [`all_messages`][pydantic_ai.agent.AgentRun.all_messages] as JSON bytes.

        Returns:
            JSON bytes representing the messages.
        	_messagesModelMessagesTypeAdapter	dump_jsonrI   r(   rK   r&   r&   r)   all_messages_json      zAgentRun.all_messages_jsonc                 C  s   |   | jjjd S )z`Return new messages for the run so far.

        Messages from older runs are excluded.
        N)rI   r8   r5   rC   r-   r&   r&   r)   new_messages   s   zAgentRun.new_messagesc                 C  rM   )zReturn new messages from [`new_messages`][pydantic_ai.agent.AgentRun.new_messages] as JSON bytes.

        Returns:
            JSON bytes representing the new messages.
        rO   rP   rQ   rU   r-   r&   r&   r)   new_messages_json   rT   zAgentRun.new_messages_json^AsyncIterator[_agent_graph.AgentNode[AgentDepsT, OutputDataT] | End[FinalResult[OutputDataT]]]c                 C  s   | S )z8Provide async-iteration over the nodes in the agent run.r&   r-   r&   r&   r)   	__aiter__   s   zAgentRun.__aiter__c                   s   t | jI dH }| |S )zGAdvance to the next node automatically based on the last returned node.N)anextr   r;   r<   r&   r&   r)   	__anext__   s   
zAgentRun.__anext__r=   DEndMarker[FinalResult[OutputDataT]] | JoinItem | Sequence[GraphTask]c                 C  sd   t |tr t|dkr |d }t |jtr |j}tj|dr |S t |tr*t|j	S t
d| )Nr   r   )nodezUnexpected node: )
isinstancer   leninputsr   r   is_agent_noder   r   valuer   AgentRunError)r(   r=   
first_task	base_noder&   r&   r)   r;      s   

zAgentRun._task_to_noder]   /_agent_graph.AgentNode[AgentDepsT, OutputDataT]r   c                 C  s   t tt|j|ddS )Nr&   )r`   
fork_stack)r   r   typeid)r(   r]   r&   r&   r)   _node_to_task   s   zAgentRun._node_to_taskc                   sB   |  |g}z| j|I dH }W n	 ty   Y nw | |S )a
  Manually drive the agent run by passing in the node you want to run next.

        This lets you inspect or mutate the node before continuing execution, or skip certain nodes
        under dynamic conditions. The agent run should be stopped when you return an [`End`][pydantic_graph.nodes.End]
        node.

        Example:
        ```python
        from pydantic_ai import Agent
        from pydantic_graph import End

        agent = Agent('openai:gpt-4o')

        async def main():
            async with agent.iter('What is the capital of France?') as agent_run:
                next_node = agent_run.next_node  # start with the first node
                nodes = [next_node]
                while not isinstance(next_node, End):
                    next_node = await agent_run.next(next_node)
                    nodes.append(next_node)
                # Once `next_node` is an End, we've finished:
                print(nodes)
                '''
                [
                    UserPromptNode(
                        user_prompt='What is the capital of France?',
                        instructions_functions=[],
                        system_prompts=(),
                        system_prompt_functions=[],
                        system_prompt_dynamic_functions={},
                    ),
                    ModelRequestNode(
                        request=ModelRequest(
                            parts=[
                                UserPromptPart(
                                    content='What is the capital of France?',
                                    timestamp=datetime.datetime(...),
                                )
                            ],
                            run_id='...',
                        )
                    ),
                    CallToolsNode(
                        model_response=ModelResponse(
                            parts=[TextPart(content='The capital of France is Paris.')],
                            usage=RequestUsage(input_tokens=56, output_tokens=7),
                            model_name='gpt-4o',
                            timestamp=datetime.datetime(...),
                            run_id='...',
                        )
                    ),
                    End(data=FinalResult(output='The capital of France is Paris.')),
                ]
                '''
                print('Final result:', agent_run.result.output)
                #> Final result: The capital of France is Paris.
        ```

        Args:
            node: The node to run next in the graph.

        Returns:
            The next node returned by the graph logic, or an [`End`][pydantic_graph.nodes.End] node if
            the run has completed.
        N)rj   r   nextStopAsyncIterationr;   )r(   r]   r=   r&   r&   r)   rk      s   G
zAgentRun.next_usage.RunUsagec                 C  rG   )zZGet usage statistics for the run so far, including token usage, model requests, and so on.)r   r4   r   r-   r&   r&   r)   r     s   
zAgentRun.usagec                 C  rG   z(The unique identifier for the agent run.)r   r4   run_idr-   r&   r&   r)   ro     s   
zAgentRun.run_idc                 C  s@   | j j}|d u r
dnt|j}dt| j d| d|   dS )Nz<run not finished><z result=z usage=>)r   r@   r   rh   __name__r   )r(   rE   result_reprr&   r&   r)   __repr__#  s   "zAgentRun.__repr__r    r!   r"   r#   r"   r,   r    r/   r"   r#   )r"   r3   )r"   r9   )r"   r?   )r"   rF   rK   r#   r"   rL   )r"   rL   )r"   rX   )r=   r\   r"   r9   )r]   rf   r"   r   )r]   rf   r"   r9   r"   rm   )rr   
__module____qualname____doc____annotations__r   r*   propertyr8   r>   rE   rI   rS   rU   rW   rY   r[   r;   rj   rk   r   ro   rt   r&   r&   r&   r)   r      s6   
 =









Or   c                   @  s$  e Zd ZU dZded< 	 ejddddZded< ejddej	d	Z
d
ed< ejddddZded< ejddddZded< ed5ddZed6ddZddd7ddZd8ddZddd9d!d"Zddd:d$d%Zddd9d&d'Zddd:d(d)Zed;d+d,Zd<d.d/Zd=d1d2Zed6d3d4ZdS )>rA   z!The final result of an agent run.r   r@   FN)r   comparedefaultr#   _output_tool_name)r   r   default_factoryz_agent_graph.GraphAgentState_stater   int_new_message_index_traceparent_valuer    r!   r"   c                C  r$   r%   r&   r'   r&   r&   r)   r*   7  r+   zAgentRunResult._traceparentr,   c                 C  r$   r%   r&   r-   r&   r&   r)   r*   9  r+   Tr.   r/   c                C  s   | j d u r|rtd| j S )Nr0   )r   r1   r'   r&   r&   r)   r*   ;  s   return_contentrF   c                 C  s   | j std| jj}|d }t|jD ]&\}}t|tjr:|j	| j kr:t
|}t|}||j| _||d< |  S qtd| j d)zSet return content for the output tool.

        Useful if you want to continue the conversation and want to set the response to the output tool call.
        zDCannot set output tool return content when the return type is `str`.z"No tool call found with tool name .)r   
ValueErrorr   rH   	enumeratepartsr^   rO   ToolReturnPartrB   listr   contentLookupError)r(   r   r   last_messageidxpartcopied_messagescopied_lastr&   r&   r)   _set_output_tool_return@  s   z&AgentRunResult._set_output_tool_returnrJ   rK   c                C  s   |dur	|  |S | jjS )a  Return the history of _messages.

        Args:
            output_tool_return_content: The return content of the tool call to set in the last message.
                This provides a convenient way to modify the content of the output tool call if you want to continue
                the conversation and want to set the response to the output tool call. If `None`, the last message will
                not be modified.

        Returns:
            List of messages.
        N)r   r   rH   rR   r&   r&   r)   rI   U  s   
zAgentRunResult.all_messagesrL   c                C     t j| j|dS )a9  Return all messages from [`all_messages`][pydantic_ai.agent.AgentRunResult.all_messages] as JSON bytes.

        Args:
            output_tool_return_content: The return content of the tool call to set in the last message.
                This provides a convenient way to modify the content of the output tool call if you want to continue
                the conversation and want to set the response to the output tool call. If `None`, the last message will
                not be modified.

        Returns:
            JSON bytes representing the messages.
        rJ   rN   rR   r&   r&   r)   rS   f     
z AgentRunResult.all_messages_jsonc                C  s   | j |d| jd S )a  Return new messages associated with this run.

        Messages from older runs are excluded.

        Args:
            output_tool_return_content: The return content of the tool call to set in the last message.
                This provides a convenient way to modify the content of the output tool call if you want to continue
                the conversation and want to set the response to the output tool call. If `None`, the last message will
                not be modified.

        Returns:
            List of new messages.
        rJ   N)rI   r   rR   r&   r&   r)   rU   v  s   zAgentRunResult.new_messagesc                C  r   )a=  Return new messages from [`new_messages`][pydantic_ai.agent.AgentRunResult.new_messages] as JSON bytes.

        Args:
            output_tool_return_content: The return content of the tool call to set in the last message.
                This provides a convenient way to modify the content of the output tool call if you want to continue
                the conversation and want to set the response to the output tool call. If `None`, the last message will
                not be modified.

        Returns:
            JSON bytes representing the new messages.
        rJ   rV   rR   r&   r&   r)   rW     r   z AgentRunResult.new_messages_json_messages.ModelResponsec                 C  s.   t |  D ]}t|tjr|  S qtd)z2Return the last response from the message history.z(No response found in the message history)reversedrI   r^   rO   ModelResponser   )r(   messager&   r&   r)   response  s
   zAgentRunResult.responserm   c                 C     | j jS )z"Return the usage of the whole run.)r   r   r-   r&   r&   r)   r        zAgentRunResult.usager   c                 C  r   )z&Return the timestamp of last response.)r   	timestampr-   r&   r&   r)   r     r   zAgentRunResult.timestampc                 C  r   rn   )r   ro   r-   r&   r&   r)   ro     s   zAgentRunResult.run_idru   rv   rw   )r   r,   r"   rF   )rK   r#   r"   rF   rx   )r"   r   ry   )r"   r   )rr   rz   r{   r|   r}   dataclassesfieldr   r   r6   r   r   r   r   r*   r   rI   rS   rU   rW   r~   r   r   r   ro   r&   r&   r&   r)   rA   )  s4   
 

	
rA   c                   @  s8   e Zd ZU dZded< 	 ded< dZded< 	 ejZd	S )
AgentRunResultEventzYAn event indicating the agent run ended and containing the final result of the agent run.zAgentRunResult[OutputDataT]rE   zdataclasses.KW_ONLY_agent_run_resultzLiteral['agent_run_result']
event_kindN)	rr   rz   r{   r|   r}   r   r   dataclasses_no_defaults_reprrt   r&   r&   r&   r)   r     s   
 
r   )-
__future__r   _annotationsr   collections.abcr   r   copyr   r   typingr   r   r	   r
   r   pydantic_graphr   r   r   pydantic_graph.beta.graphr   r   r   r   pydantic_graph.beta.stepr    r   r   r   r   rO   r   _usager@   r   toolsr   rE   r   	dataclassr   rA   r   r&   r&   r&   r)   <module>   s.    
   
