
    iR                        U d Z ddlZddlZddl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 ddlZ ej        e          ZdZdZi ae
ee	f         ed	<   daeed
<   e G d d                      Ze G d d                      Zi ddddddddddddddddddddddddddddddd d!d"d#d$d%d&d'd(d(d)d*d+d,d-d.d/d0d1d2Ze
eef         ed3<   dZee
eef                  ed4<   d5efd6Zd5e
ee	f         fd7Z d8e
ee	f         d5dfd9Z!dUd;e"d5e
ee	f         fd<Z#d=ed>ed5ee$         fd?Z%d@e
ee	f         d5ee$         fdAZ&e G dB dC                      Z'd=ed5ee
ee	f                  fdDZ(dEe
ee	f         d>ed5ee
ee	f                  fdFZ)d=ed>ed5ee'         fdGZ*d=ed5ee         fdHZ+ddl,Z, e,j-        dIe,j.                  Z/e,j0        edJ<    e1h dK          Z2d=edLed5e"fdMZ3d=ed5ee         fdNZ4dLedOe
ee	f         dPed5efdQZ5dPedOe
ee	f         d5efdRZ6dPed5ee         fdSZ7dPedLed5ee         fdTZ8dS )Vu]  Models.dev registry integration — primary database for providers and models.

Fetches from https://models.dev/api.json — a community-maintained database
of 4000+ models across 109+ providers.  Provides:

- **Provider metadata**: name, base URL, env vars, documentation link
- **Model metadata**: context window, max output, cost/M tokens, capabilities
  (reasoning, tools, vision, PDF, audio), modalities, knowledge cutoff,
  open-weights flag, family grouping, deprecation status

Data resolution order (like TypeScript OpenCode):
  1. Bundled snapshot (ships with the package — offline-first)
  2. Disk cache (~/.hermes/models_dev_cache.json)
  3. Network fetch (https://models.dev/api.json)
  4. Background refresh every 60 minutes

Other modules should import the dataclasses and query functions from here
rather than parsing the raw JSON themselves.
    N)	dataclass)Path)AnyDictListOptionalTuple)atomic_json_writezhttps://models.dev/api.jsoni  _models_dev_cache_models_dev_cache_timec                      e Zd ZU dZeed<   eed<   eed<   eed<   dZeed<   dZeed<   dZ	eed	<   dZ
eed
<   dZeed<   dZeed<   dZeedf         ed<   dZeedf         ed<   dZeed<   dZeed<   dZee         ed<   dZeed<   dZeed<   dZee         ed<   dZee         ed<   dZeed<   dZeed<   dZeed<   dZeed<   d efd!Zd efd"Z d efd#Z!d efd$Z"d efd%Z#d efd&Z$dS )'	ModelInfoz1Full metadata for a single model from models.dev.idnamefamilyprovider_idF	reasoning	tool_call
attachmenttemperaturestructured_outputopen_weights .input_modalitiesoutput_modalitiesr   context_window
max_outputN	max_inputg        
cost_inputcost_outputcost_cache_readcost_cache_write knowledge_cutoffrelease_datestatusinterleavedreturnc                 .    | j         dk    p
| j        dk    S )Nr   )r   r    selfs    5/home/ubuntu/.hermes/hermes-agent/agent/models_dev.pyhas_cost_datazModelInfo.has_cost_dataT   s    ":d&6&::    c                 "    | j         pd| j        v S )Nimage)r   r   r*   s    r,   supports_visionzModelInfo.supports_visionW   s    B'T-B"BBr.   c                     d| j         v S )Npdfr   r*   s    r,   supports_pdfzModelInfo.supports_pdfZ   s    ---r.   c                     d| j         v S )Naudior4   r*   s    r,   supports_audio_inputzModelInfo.supports_audio_input]   s    $///r.   c                     |                                  sdS d| j        ddd| j        ddg}| j        |                    d| j        dd           d	                    |          S )
z<Human-readable cost string, e.g. '$3.00/M in, $15.00/M out'.unknown$z.2fz/M inz/M outNzcache read $z/M, )r-   r   r    r!   appendjoin)r+   partss     r,   format_costzModelInfo.format_cost`   s    !!## 	9/T_////1QT5E1Q1Q1Q1QR+LLD(<DDDDEEEyyr.   c                    g }| j         r|                    d           | j        r|                    d           |                                 r|                    d           |                                 r|                    d           |                                 r|                    d           | j        r|                    d           | j        r|                    d           |rd                    |          nd	S )
zBHuman-readable capabilities, e.g. 'reasoning, tools, vision, PDF'.r   toolsvisionPDFr7   zstructured outputzopen weightsr<   basic)	r   r=   r   r1   r5   r8   r   r   r>   )r+   capss     r,   format_capabilitieszModelInfo.format_capabilitiesi   s   > 	%KK$$$> 	!KK   !! 	"KK!!! 	KK$$&& 	!KK   ! 	-KK+,,, 	(KK'''"&3tyyG3r.   )%__name__
__module____qualname____doc__str__annotations__r   boolr   r   r   r   r   r   r	   r   r   intr   r   r   r   floatr    r!   r"   r$   r%   r&   r'   r   r-   r1   r5   r8   r@   rG   r   r.   r,   r   r   .   sE        ;;GGG
IIIKKK ItItJK#t###L$ )+eCHo***)+uS#X+++ NCJ#Ix}### JK'+OXe_+++(,huo,,, cL#FCK;t ; ; ; ;C C C C C.d . . . .0d 0 0 0 0 S        4S 4 4 4 4 4 4r.   r   c                   h    e Zd ZU dZeed<   eed<   eedf         ed<   eed<   dZeed<   d	Ze	ed
<   dS )ProviderInfoz-Full metadata for a provider from models.dev.r   r   .envapir#   docr   model_countN)
rH   rI   rJ   rK   rL   rM   r	   rU   rV   rO   r   r.   r,   rR   rR   }   sd         77GGG
III	sCx	HHHCMMMKr.   rR   
openrouter	anthropicopenaizopenai-codexzaizkimi-codingzkimi-for-codingstepfunzkimi-coding-cnminimaxzminimax-oauthz
minimax-cndeepseekalibabaz
qwen-oauthcopilotzgithub-copilotz
ai-gatewayvercelzopencode-zenopencodeopencode-gokilozfireworks-aihuggingfacegooglexaixiaominvidiagroqmistral
togetherai
perplexitycohereollama-cloud)rb   kilocode	fireworksrd   geminire   rf   rg   rh   ri   rj   rk   rl   rm   rn   PROVIDER_TO_MODELS_DEV_MODELS_DEV_TO_PROVIDERr(   c                  (    ddl m}   |             dz  S )zReturn path to disk cache file.r   get_hermes_homezmodels_dev_cache.json)hermes_constantsrv   ru   s    r,   _get_cache_pathrx      s(    000000?666r.   c                  ,   	 t                      } |                                 r=t          | d          5 }t          j        |          cddd           S # 1 swxY w Y   n2# t
          $ r%}t                              d|           Y d}~nd}~ww xY wi S )z%Load models.dev data from disk cache.zutf-8)encodingNz(Failed to load models.dev disk cache: %s)rx   existsopenjsonload	Exceptionloggerdebug)
cache_pathfes      r,   _load_disk_cacher      s    D$&&
 	$j7333 $qy||$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ D D D?CCCCCCCCDIs:   3A" A	A" AA" AA" "
B,BBdatac                     	 t                      }t          || dd           dS # t          $ r&}t                              d|           Y d}~dS d}~ww xY w)z.Save models.dev data to disk cache atomically.N),:)indent
separatorsz(Failed to save models.dev disk cache: %s)rx   r
   r   r   r   )r   r   r   s      r,   _save_disk_cacher      sz    D$&&
*d4JOOOOOO D D D?CCCCCCCCCDs   !% 
AAAFforce_refreshc           	      R   | s2t           r+t          j                    t          z
  t          k     rt           S 	 t	          j        t          d          }|                                 |                                }t          |t                    rz|rx|a t          j                    at          |           t                              dt          |          t          d |                                D                                  |S n2# t"          $ r%}t                              d|           Y d}~nd}~ww xY wt           s`t%                      a t           rKt          j                    t          z
  dz   at                              dt          t                                t           S )	zFetch models.dev registry. In-memory cache (1hr) + disk fallback.

    Returns the full registry dict keyed by provider ID, or empty dict on failure.
       )timeoutz:Fetched models.dev registry: %d providers, %d total modelsc              3      K   | ]<}t          |t                    t          |                    d i                     V  =dS )modelsN)
isinstancedictlenget).0ps     r,   	<genexpr>z#fetch_models_dev.<locals>.<genexpr>   sI      [[zRSUYGZGZ[Ch++,,[[[[[[r.   zFailed to fetch models.dev: %sNi,  z0Loaded models.dev from disk cache (%d providers))r   timer   _MODELS_DEV_CACHE_TTLrequestsr   MODELS_DEV_URLraise_for_statusr}   r   r   r   r   r   r   sumvaluesr   r   )r   responser   r   s       r,   fetch_models_devr      s    !! Y[[115JJJ  :<;;;!!###}}dD!! 		d 		 $%)Y[["T"""LLLD		[[dkkmm[[[[[  
 K : : :5q99999999:
  e,.. 	e%)Y[[3H%H3%N"LLKSQbMcMcddds   CD	 	
D8D33D8providermodelc                    t                               |           }|sdS t                      }|                    |          }t          |t                    sdS |                    di           }t          |t                    sdS |                    |          }|rt          |          }|r|S |                                }|                                D ]2\  }	}
|	                                |k    rt          |
          }|r|c S 3dS )zLook up context_length for a provider+model combo in models.dev.

    Returns the context window in tokens, or None if not found.
    Handles case-insensitive matching and filters out context=0 entries.
    Nr   )rr   r   r   r   r   _extract_contextloweritems)r   r   mdev_provider_idr   provider_datar   entryctxmodel_lowermidmdatas              r,   lookup_models_dev_contextr      s    .11(;; tDHH-..MmT** tx,,Ffd## t JJuE u%% 	J ++--Kllnn  
U99;;+%%"5))C 


4r.   r   c                    t          | t                    sdS |                     d          }t          |t                    sdS |                    d          }t          |t          t          f          r|dk    rt          |          S dS )zExtract context_length from a models.dev model entry.

    Returns None for invalid/zero values (some audio/image models have context=0).
    Nlimitcontextr   )r   r   r   rO   rP   )r   r   r   s      r,   r   r   "  s    
 eT"" tIIgEeT"" t
))I

C#U|$$ q3xx4r.   c                   h    e Zd ZU dZdZeed<   dZeed<   dZeed<   dZ	e
ed<   d	Ze
ed
<   dZeed<   dS )ModelCapabilitiesz;Structured capability metadata for a model from models.dev.Tsupports_toolsFr1   supports_reasoning@ r       max_output_tokensr#   model_familyN)rH   rI   rJ   rK   r   rN   rM   r1   r   r   rO   r   r   rL   r   r.   r,   r   r   7  sz         EEND!OT!!!$$$$ NC   !s!!!L#r.   r   c                    t                               |           }|sdS t                      }|                    |          }t          |t                    sdS |                    di           }t          |t                    sdS |S )zResolve a Hermes provider ID to its models dict from models.dev.

    Returns the models dict or None if the provider is unknown or has no data.
    Nr   )rr   r   r   r   r   )r   r   r   r   r   s        r,   _get_provider_modelsr   C  s    
 .11(;; tDHH-..MmT** tx,,Ffd## tMr.   r   c                    |                      |          }t          |t                    r|S |                                }|                                 D ]6\  }}|                                |k    rt          |t                    r|c S 7dS )zBFind a model entry by exact match, then case-insensitive fallback.N)r   r   r   r   r   )r   r   r   r   r   r   s         r,   _find_model_entryr   X  s     JJuE%  ++--Kllnn  
U99;;+%%*UD*A*A%LLL4r.   c                    t          |           }|dS t          ||          }|dS t          |                    dd                    }|                    di           }t	          |t
                    r|                    dg           }ng }t          |                    dd                    pd|v }t          |                    dd                    }|                    d	i           }t	          |t
                    si }|                    d
          }	t	          |	t          t          f          r|	dk    rt          |	          nd}
|                    d          }t	          |t          t          f          r|dk    rt          |          nd}|                    dd          pd}t          ||||
||          S )u  Look up full capability metadata from models.dev cache.

    Uses the existing fetch_models_dev() and PROVIDER_TO_MODELS_DEV mapping.
    Returns None if model not found.

    Extracts from model entry fields:
      - reasoning  (bool)  → supports_reasoning
      - tool_call  (bool)  → supports_tools
      - attachment (bool)  → supports_vision
      - limit.context (int) → context_window
      - limit.output  (int) → max_output_tokens
      - family     (str)   → model_family
    Nr   F
modalitiesinputr   r0   r   r   r   r   r   outputr   r   r#   )r   r1   r   r   r   r   )	r   r   rN   r   r   r   rO   rP   r   )r   r   r   r   r   
input_modsr1   r   r   r   r   outr   r   s                 r,   get_model_capabilitiesr   h  s    "(++F~tfe,,E}t %))K7788N <,,J*d## ^^GR00


599\599::Sg>SOeiiU;;<< IIgr""EeT"" 
))I

C!+C#u!>!>V377SXXXPVN
))H

C$.sS%L$A$AWcAggCSW99Xr**0bL%'-%+!   r.   c                      ddl m}  |           p  t                     }|g S  fd|                                D             S )zReturn all model IDs for a provider from models.dev.

    Returns an empty list if the provider is unknown or has no data.
    r   )normalize_providerNc                 4    g | ]}t          |          |S r   )"_should_hide_from_provider_catalog)r   r   r   s     r,   
<listcomp>z(list_provider_models.<locals>.<listcomp>  s9       1(C@@  r.   )hermes_cli.modelsr   r   keys)r   r   r   s   `  r,   list_provider_modelsr     sv    
 544444!!(++7xH!(++F~	   {{}}   r.   zZ-tts\b|embedding|live-|-(preview|exp)-\d{2,4}[-_]|-image\b|-image-preview\b|-customtools\b_NOISE_PATTERNS>   
gemma-3-1b
gemma-3-2b
gemma-3-4bgemma-3-12bgemma-3-27bgemma-3-1b-itgemma-3-2b-itgemma-3-4b-itgemini-1.5-progemma-3-12b-itgemma-3-27b-itgemma-4-26b-itgemma-4-31b-itgemini-1.5-flashgemini-2.0-flashgemma-4-26b-a4b-itgemini-1.5-flash-8bgemini-2.0-flash-litemodel_idc                     | pd                                                                 }|pd                                                                 }|dv r|t          v rdS dS )Nr#   >   rq   re   TF)stripr   _GOOGLE_HIDDEN_MODELS)r   r   provider_lowerr   s       r,   r   r     se    n"++--3355N>r((**0022K---+AV2V2Vt5r.   c                 @   t          |           }|g S g }|                                D ]s\  }}t          |t                    st	          | |          r,|                    dd          sCt                              |          r^|                    |           t|S )zReturn model IDs suitable for agentic use from models.dev.

    Filters for tool_call=True and excludes noise (TTS, embedding,
    dated preview snapshots, live/streaming, image-only models).
    Returns an empty list on any failure.
    Nr   F)	r   r   r   r   r   r   r   searchr=   )r   r   resultr   r   s        r,   list_agentic_modelsr     s     "(++F~	Fllnn 	 	
U%&& 	-h<< 	yye,, 	!!#&& 	cMr.   rawr   c                    |                     d          pi }t          |t                    si }|                     d          pi }t          |t                    si }|                     d          pi }t          |t                    si }|                     d          pg }|                     d          pg }|                     d          }t          |t          t          f          r|dk    rt          |          nd}	|                     d          }
t          |
t          t          f          r|
dk    rt          |
          nd}|                     d          }t          |t          t          f          r|dk    rt          |          nd}t          di d	| d
|                     d
d          p| d|                     dd          pdd|dt          |                     dd                    dt          |                     dd                    dt          |                     dd                    dt          |                     dd                    dt          |                     dd                    dt          |                     dd                    dt          |t                    rt          |          nddt          |t                    rt          |          ndd|	d|d|dt	          |                     dd          pd          dt	          |                     dd          pd          dd|v r|d         t	          |d                   nddd |v r|d          t	          |d                    ndd!|                     d"d          pdd#|                     d#d          pdd$|                     d$d          pdd%|                     d%d          S )&zEConvert a raw models.dev model entry dict into a ModelInfo dataclass.r   costr   r   r   r   r   Nr   r   r#   r   r   r   Fr   r   r   r   r   r   r   r   r   r   r   r   r    r!   
cache_readr"   cache_writer$   	knowledger%   r&   r'   )	r   r   r   rO   rP   r   rN   listtuple)r   r   r   r   r   r   r   output_modsr   ctx_intr   out_intinpinp_ints                 r,   _parse_model_infor     s@   GGG"EeT"" 776?? bDdD!! &&,"Jj$'' 
((.BJ..**0bK
))I

C$S3,77JC!GGc#hhhG
))H

C$S3,77JC!GGc#hhhG
))G

C$S3,77MC!GGc#hhhG   8WWVR  ,H wwx$$*  K	
 sww{E22333 sww{E22333 e44555 66777 sww':EBBCCC #''.%88999 /9T.J.JRz***PR 1;;0M0MU%,,,SU w 7 '  '1--2333!" $((8Q//41555#$ 6BT5I5IdS_N`Nld<0111rv%& 8E7L7LQUVcQdQptM2333vz'( b117R)* WW^R006B+, wwx$$*-. GGM5111/ r.   c                    |                     d          pg }|                     d          pi }t          | |                     dd          p| t          |t                    rt	          |          nd|                     dd          pd|                     dd          pdt          |t
                    rt          |          nd	          S )
zAConvert a raw models.dev provider entry dict into a ProviderInfo.rS   r   r   r#   r   rT   rU   r   )r   r   rS   rT   rU   rV   )r   rR   r   r   r   r   r   )r   r   rS   r   s       r,   _parse_provider_infor   2  s    
''%..
BCWWX$"FWWVR  /K$S$//7E#JJJRGGE2$"GGE2$"#-fd#;#;BCKKK   r.   c                     t                               | |           }t                      }|                    |          }t          |t                    sdS t          ||          S )zGet full provider metadata from models.dev.

    Accepts either a Hermes provider ID (e.g. "kilocode") or a models.dev
    ID (e.g. "kilo").  Returns None if the provider is not in the catalog.
    N)rr   r   r   r   r   r   )r   mdev_idr   r   s       r,   get_provider_infor   D  s\     %((kBBGD
((7

Cc4   t---r.   c                 \   t                               | |           }t                      }|                    |          }t          |t                    sdS |                    di           }t          |t                    sdS |                    |          }t          |t                    rt          |||          S |                                }|                                D ]E\  }}	|                                |k    r(t          |	t                    rt          ||	|          c S FdS )zGet full model metadata from models.dev.

    Accepts Hermes or models.dev provider ID.  Tries exact match then
    case-insensitive fallback.  Returns None if not found.
    Nr   )rr   r   r   r   r   r   r   r   )
r   r   r   r   pdatar   r   r   r   r   s
             r,   get_model_infor   Y  s    %((kBBGDHHWEeT"" tYYx$$Ffd## t **X

C#t 9 3888 ..""Kllnn : :
U99;;+%%*UD*A*A%$S%999994r.   )F)9rK   r}   loggingr   dataclassesr   pathlibr   typingr   r   r   r   r	   utilsr
   r   	getLoggerrH   r   r   r   r   rL   rM   r   rP   r   rR   rr   rs   rx   r   r   rN   r   rO   r   r   r   r   r   r   r   recompile
IGNORECASEr   Pattern	frozensetr   r   r   r   r   r   r   r   r.   r,   <module>r     s    (    ! ! ! ! ! !       3 3 3 3 3 3 3 3 3 3 3 3 3 3 # # # # # # 		8	$	$.  %' 4S> & & & !  ! ! ! K4 K4 K4 K4 K4 K4 K4 K4\         !*,!*!* h!* H	!*
 
5!* $!* y!* '!* y!* Y!* ,!* 
!* y!* )!* !*  (!!*" J#!*$ ! "A!* !* !* S#X ! ! !H 59 $sCx.1 8 8 87 7 7 7 7	$sCx. 	 	 	 	D4S> Dd D D D D) )D )T#s(^ ) ) ) )X" "C "HSM " " " "JDcN x}    *        3 8DcN+C    *d38n S Xd3PS8n=U     6S 6 6BS9T 6 6 6 6r3 49    & 
			(bj0M     "	 # # #   4      # $s)    <0 0$sCx. 0s 0y 0 0 0 0fc S#X <    $.3 .8L+A . . . .* #i     r.   