o
    $iQ                     @   sh   d 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mZmZ eeZG dd dZdS )z"
OpenRouter Agent implementation.
    N)AnyCallableDictListOptional)MessageRoleToolc                   @   s6  e Zd ZdZ						d-ded	ed
ededededeeee	f  fddZ
dededeeef defddZde	ddfddZ	d.deeeef  deeeeef   deeef fddZdee dee fddZd eddfd!d"Z		#d/d$ed%ee d&edefd'd(Zdeeeef  fd)d*Zd0d+d,ZdS )1OpenRouterAgentz:AI Agent using OpenRouter API with tool calling capabilityqwen/qwen3-coder-nexthttps://openrouter.ai/api/v1ffffff?   
   Napi_keymodelbase_urltemperature
max_tokensmax_iterationstoolsc                 C   sT   || _ || _|| _|| _|| _|| _|r|ni | _g | _d| j  dddd| _dS )a  
        Initialize the OpenRouter agent.
        
        Args:
            api_key: OpenRouter API key
            model: Model identifier (default: "qwen/qwen3-coder-next")
            base_url: OpenRouter API base URL
            temperature: Sampling temperature
            max_tokens: Maximum tokens to generate
            max_iterations: Maximum tool-calling iterations
            tools: Optional dictionary of pre-registered tools
        zBearer zapplication/jsonzhttps://github.comzAI Agent)AuthorizationzContent-TypezHTTP-RefererzX-TitleN)	r   r   r   r   r   r   r   conversation_historyheaders)selfr   r   r   r   r   r   r    r   0/var/www/apps/myagent/mysuperagent/core/agent.py__init__   s   
zOpenRouterAgent.__init__namedescription
parametersreturnc                    s    dt dt f fdd}|S )z%Decorator to register a tool functionfuncr!   c                    s   t  | d}|j< | S )N)r   r   r    function)r	   r   )r"   toolr   r   r    r   r   r   	decorator?   s   
z0OpenRouterAgent.register_tool.<locals>.decorator)r   )r   r   r   r    r&   r   r%   r   register_tool8   s   	zOpenRouterAgent.register_toolr$   c                 C   s   || j |j< dS )zAdd a tool to the agentN)r   r   )r   r$   r   r   r   add_toolJ      zOpenRouterAgent.add_toolmessagesc                 C   sL   | j || j| jd}|r||d< tj| j d| j|dd}|  | S )zMake API call to OpenRouter)r   r*   r   r   r   z/chat/completions   )r   jsontimeout)	r   r   r   requestspostr   r   raise_for_statusr,   )r   r*   r   payloadresponser   r   r   _make_api_callN   s   
zOpenRouterAgent._make_api_call
tool_callsc           	      C   s   g }|D ]S}|d d }t |d d }|| jv rC| j| j}z	|d	i |}W n tyB } zdt| }W Y d}~n
d}~ww d| }|ttj	t||d d q|S )
z2Process tool calls and return tool result messagesr#   r   	argumentszError: NzError: Unknown tool id)rolecontenttool_call_idr   )
r,   loadsr   r#   	Exceptionstrappendr   r   TOOL)	r   r4   tool_messages	tool_call	func_name	func_argsr"   resulter   r   r   _process_tool_callsg   s*   

z#OpenRouterAgent._process_tool_callsmessagec                 C   s   | j | dS )z)Add a message to the conversation historyN)r   r=   )r   rF   r   r   r   add_message   r)   zOpenRouterAgent.add_messageF
user_inputsystem_promptreset_conversationc                 C   s`  |rg | _ |rtdd | j D s| ttj|d | ttj|d d}d}|| jk r|d7 }t	d| d| j  d	d
 | j D }d}| j
rUdd
 | j
 D }| ||}|d d }	|	d }
d|
v r|
d rttj|
d|
d d}| | | |
d }|D ]}| | qq)ttj|
ddd}| | |
dd}	 |du rd}|S )aF  
        Main agentic loop: Process user input and handle tool calls
        
        Args:
            user_input: User's message
            system_prompt: Optional system prompt
            reset_conversation: Whether to reset conversation history
            
        Returns:
            Final assistant response
        c                 s   s    | ]	}|j tjkV  qd S N)r7   r   SYSTEM).0mr   r   r   	<genexpr>   s    z&OpenRouterAgent.run.<locals>.<genexpr>)r7   r8   r   N   z
Iteration /c                 S      g | ]}|  qS r   to_dictrM   msgr   r   r   
<listcomp>       z'OpenRouterAgent.run.<locals>.<listcomp>c                 S   rR   r   rS   )rM   r$   r   r   r   rW      rX   choicesrF   r4   r8   )r7   r8   r4    z2Maximum iterations reached without final response.)r   anyrG   r   r   rL   USERr   loggerinfor   valuesr3   	ASSISTANTgetrE   )r   rH   rI   rJ   	iterationfinal_responser*   
tools_listr2   choicerF   assistant_messager?   tool_msgr   r   r   run   sL   



zOpenRouterAgent.runc                 C   s   dd | j D S )z1Get the conversation history in a readable formatc                 S   rR   r   rS   rU   r   r   r   rW      rX   z<OpenRouterAgent.get_conversation_history.<locals>.<listcomp>r   r   r   r   r   get_conversation_history   r)   z(OpenRouterAgent.get_conversation_historyc                 C   s
   g | _ dS )zClear the conversation historyNri   rj   r   r   r   clear_history   s   
zOpenRouterAgent.clear_history)r   r   r   r   r   NrK   )NF)r!   N)__name__
__module____qualname____doc__r<   floatintr   r   r	   r   r   r   r'   r(   r   r3   r   rE   rG   boolrh   rk   rl   r   r   r   r   r
      sp    
&




Ir
   )rp   r,   loggingr.   typingr   r   r   r   r   core.modelsr   r   r	   	getLoggerrm   r]   r
   r   r   r   r   <module>   s    
