o
    xi!                     @   s   d dl Z d dlZd dlZd dlmZmZmZmZ ddlm	Z	 ddl
mZ d dlZG dd dZG dd	 d	eZG d
d deZG dd deZG dd deZG dd deZG dd deZG dd deZddee	 deeef fddZdS )    N)DictAnyListOptional   )UserInterfaceAdapter)ui_statec                   @   s<   e Zd ZU dZeed< eed< deeef defddZdS )	BaseToolzCommon interface for all tools.namedescriptionargsreturnc                 C   s   t N)NotImplementedError)selfr    r   5/var/www/apps/myagent/mysuperagent/agent_src/tools.pyrun   s   zBaseTool.runN)	__name__
__module____qualname____doc__str__annotations__r   r   r   r   r   r   r   r	      s
   
 r	   c                   @   s`   e Zd ZdZdZdd eeD eee	e
dB Zdede
fdd	Zd
eeef defddZdS )CalcToolcalczEvaluate a simple arithmetic expression. Supported operators: + - * / ** and parentheses. Example args: {"expression": "2 * (3 + 4)"}c                 C   s"   i | ]}| d s|tt|qS )__)
startswithgetattrmath).0kr   r   r   
<dictcomp>   s
    

zCalcTool.<dictcomp>)absroundintfloatexprr   c                 C   s&   t d|s
tdt|di i| jS )Nz[0-9\s\.\+\-\*\/\(\)\^\%]+z&Expression contains illegal characters__builtins__)re	fullmatch
ValueErroreval_allowed_names)r   r'   r   r   r   
_safe_eval#   s   zCalcTool._safe_evalr   c              
   C   sX   | d}|s	dS z| |}d| W S  ty+ } zd| W  Y d }~S d }~ww )N
expressionu"   ❌ Missing 'expression' argument.u   ✅ Result = u   ❌ Calculator error: )getr.   	Exception)r   r   r'   resulter   r   r   r   (   s   

zCalcTool.runN)r   r   r   r
   r   dirr   r#   r$   r%   r&   r-   r   r.   r   r   r   r   r   r   r   r      s    r   c                   @   .   e Zd ZdZdZdeeef defddZdS )
SearchToolsearchzpSearch the web for a short query and return the top result snippet. Example args: {"query": "capital of Norway"}r   r   c                 C   s   | d}|s	dS d| dS )Nqueryu   ❌ Missing 'query' argument.u   🔎 (stub) Top result for 'z&': <pretend we fetched something here>)r0   )r   r   r8   r   r   r   r   <   s   
zSearchTool.runN	r   r   r   r
   r   r   r   r   r   r   r   r   r   r6   5   
    r6   c                   @   r5   )ReadFileTool	read_fileuY   Read a UTF‑8 text file from the local filesystem. Example args: {"path": "./notes.txt"}r   r   c              
   C   s   | d}|s	dS tj|}tjt }||sdS tj|s)d| S z(t|ddd}|d}d	| d
| W  d    W S 1 sJw   Y  W d S  t	yh } zd| W  Y d }~S d }~ww )Npath   ❌ Missing 'path' argument.u?   ❌ Access to paths outside the current directory is forbidden.   ❌ File not found: rutf-8encodingi  u   📄 Content of z (truncated):
u   ❌ Could not read file: )
r0   osr=   abspathgetcwdr   isfileopenreadr1   )r   r   r=   	safe_pathcwdfcontentr3   r   r   r   r   M   s$   



(zReadFileTool.runNr9   r   r   r   r   r;   F   r:   r;   c                   @   r5   )WriteFileTool
write_fileui   Create or overwrite a UTF‑8 text file. Example args: {"path": "./data.txt", "content": "Hello, world!"}r   r   c              
   C   s   | d}| dd}|sdS tj|}tjt }||s$dS z't|ddd}|| W d    n1 s<w   Y  d	t| d
| W S  t	yb } zd| W  Y d }~S d }~ww )Nr=   rM    r>   u<   ❌ Refusing to write outside the current working directory.wrA   rB   u
   ✅ Wrote z characters to u   ❌ Failed to write file: )
r0   rD   r=   rE   rF   r   rH   writelenr1   )r   r   r=   rM   rJ   rK   rL   r3   r   r   r   r   g   s"   

zWriteFileTool.runNr9   r   r   r   r   rN   `   r:   rN   c                   @   r5   )DeleteFileTooldelete_filezLDelete a file from the local filesystem. Example args: {"path": "./old.txt"}r   r   c              
   C   s   | d}|s	dS tj|}tjt }||sdS tj|s)d| S zt| d| W S  tyK } zd| W  Y d }~S d }~ww )Nr=   r>   u=   ❌ Refusing to delete outside the current working directory.r?   u   ✅ Deleted file u   ❌ Could not delete file: )	r0   rD   r=   rE   rF   r   rG   remover1   )r   r   r=   rJ   rK   r3   r   r   r   r      s    



zDeleteFileTool.runNr9   r   r   r   r   rT   y   r:   rT   c                   @   r5   )ListFilesTool
list_fileszrList files in a directory (optionally filter by extension). Example args: {"directory": "./", "extension": ".txt"}r   r   c              
      s   | dd}| d tj|}tjt }||s dS tj|s+d| S z$t|} r< fdd|D }|sHd| d	  d
W S dd| W S  t	yf } zd| W  Y d }~S d }~ww )N	directory.	extensionu;   ❌ Refusing to list outside the current working directory.u   ❌ Not a directory: c                    s   g | ]	}|  r|qS r   )endswith)r    r3   extr   r   
<listcomp>   s    z%ListFilesTool.run.<locals>.<listcomp>u   🔍 No files found in z with extension 'z'.u   📂 Files:

u   ❌ Error while listing files: )
r0   rD   r=   rE   rF   r   isdirlistdirjoinr1   )r   r   rY   safe_dirrK   entriesr3   r   r]   r   r      s&   



zListFilesTool.runNr9   r   r   r   r   rW      r:   rW   c                   @   sX   e Zd ZdZdZdZddee fddZdde	e
ef d	ee	e
ef  d
e
fddZdS )AskUserToolzPrompt the real user; supports both sync (CLI) and modal web via token.
    When used with a web adapter, returns {'awaiting': token, 'prompt': text}.
    ask_userzuAsk the person running the agent a question and return their answer. Example args: {"question": "What is your name?"}N
ui_adapterc                 C   s
   || _ d S r   rh   )r   rh   r   r   r   __init__   s   
zAskUserTool.__init__r   contextr   c              
   C   s   | dd}tt}| jrEt| jddrEz| j|}|d| d| W S  tyD } z|	d| d| W  Y d }~S d }~ww t
 }|d	|| ||d
S )NquestionzPlease provide input:supports_syncFzAskUserTool sync answered: %su   🗣️  User answered: z%Error during AskUserTool sync ask: %su   ❌ Error while asking user: z+AskUserTool created token %s for prompt: %s)awaitingprompt)r0   logging	getLoggerr   rh   r   ask_syncinfor1   	exceptionr   	new_token)r   r   rk   rl   loggeransr3   tokenr   r   r   r      s   

zAskUserTool.runr   )r   r   r   r   r
   r   r   r   rj   r   r   r   r   r   r   r   r   rf      s    0rf   rh   r   c                 C   s>   t jt  tjt tjt tjt tjt tjt tjt| iS )z
    Returns a dictionary mapping tool names to instantiated tool objects.
    Add any new tool class to this dictionary to make it visible to the agent.
    )r   r
   r6   r;   rN   rT   rW   rf   ri   r   r   r   build_tool_registry   s   
ry   r   )rD   r   r)   typingr   r   r   r   
interfacesr   rP   r   rp   r	   r   r6   r;   rN   rT   rW   rf   r   ry   r   r   r   r   <module>   s      $"