+
    Vi's                         R t ^ RIHtHtHtHt ^RIHtHt R R lt	R R lt
R R ltR	tRR R lltR R ltR R R lltR R ltRR R lltR R ltR R ltR R ltR R ltR R ltR
# )!z3
Shared validation functions for Firecrawl v2 API.
)OptionalDictAnyList)ScrapeOptionsScrapeFormatsc                0    V ^8  d   QhR\         R\         /# )   
format_strreturn)str)formats   "\/home/ubuntu/hermes-agent/venv/lib/python3.14/site-packages/firecrawl/v2/utils/validation.py__annotate__r   	   s     6 6s 6s 6    c                4    RRRRRR/pVP                  W 4      # )z
Convert format string from snake_case to camelCase.

Args:
    format_str: Format string in snake_case
    
Returns:
    Format string in camelCase
raw_htmlrawHtmlchange_trackingchangeTrackingscreenshot_full_pagezscreenshot@fullPage)get)r
   format_mappings   & r   _convert_format_stringr   	   s/     	I+ 5N
 j55r   c                0    V ^8  d   QhR\         R\         /# r	   schemar   r   )r   s   "r   r   r      s     O$ O$ O$ O$r   c                ~   aa V '       d   \        V \        4      '       g   V # \        4       oR VV3R lloS! V 4      # )z
Normalize a schema for OpenAI compatibility by handling recursive references.

Args:
    schema: Schema to normalize
    
Returns:
    Normalized schema
c                0    V ^8  d   QhR\         R\         /# r	   objr   r   )r   s   "r   r   1normalize_schema_for_openai.<locals>.__annotate__*   s     > >c >c >r   c                 n  < \        V \        4      '       g1   \        V \        4      '       d   V  Uu. uF  pS! V4      NK  	  up# V # \        V 4      pVS9   d   V # SP	                  V4       \        V 4      pR V9   d   SP                  V4       V# RV9   d   VP                  R4      p/ pVP                  4        F2  w  rg\        V\        4      '       d   R V9  d   S! V4      WV&   K.  WuV&   K4  	  / pVP                  4        F  w  rgS! V4      W&   K  	  / VCRV/Cp	SP                  V4       V	# VP                  R4      R8X  d    RV9   d   VP                  R4      RJ d   VR VP                  R4      R8X  d   RV9   d}   RV9   dv   \        VR,          \        4      '       dV   \        VR,          \        4      '       d9   VR,           U
u. uF  p
WR,          9   g   K  V
NK  	  pp
V'       d   WR&   MVR MVR \        VP                  4       4       Fx  w  rg\        V\        4      '       d   R V9  d   S! V4      W6&   K.  \        V\        4      '       g   KF  V Uu. uF#  p\        V\        4      '       d	   S! V4      MTNK%  	  upW6&   Kz  	  SP                  V4       V# u upi u up
i u upi )$ref$defstypeobject
propertiesadditionalPropertiesTrequired)	
isinstancedictlistidadddiscardpopitemsr   )r!   itemobj_id
normalizeddefsprocessed_restkeyvaluenormalized_defsresultfieldvalid_requirednormalize_objectvisiteds   &           r   r>   5normalize_schema_for_openai.<locals>.normalize_object*   s   #t$$#t$$;>?34(.3??JCWJF#Y
 ZOOF#j >>'*DN(..0
eT**vU/B*:5*AN'*/3'	 1 !O"jjl
'7'>$ + BAAFOOF#MNN6"h.J&NN12d:12NN6"h.*$J&:j1488:l3T::5?
5K "E5KE"'l+C"C #(%5K "E!-;z*":.z*z//12JC%&&6+>"25"9
E4((jo"pjobfZd=S=S#3D#9Y]#]jo"p
	 3 	w @V"E #qs   J(J-$J-#)J2r+   r,   set)r   r>   r?   s   &@@r   normalize_schema_for_openairC      s8     FD11eG> >@ F##r   c                0    V ^8  d   QhR\         R\        /# r   r   bool)r   s   "r   r   r   m   s     2- 2-s 2-t 2-r   c                   aa V '       d   \        V \        4      '       g   R# \        4       oR VV3R lloS! V 4      '       * # )z
Validate schema for OpenAI compatibility.

Args:
    schema: Schema to validate
    
Returns:
    True if schema is valid, False otherwise
Tc                0    V ^8  d   QhR\         R\        /# r    rE   )r   s   "r   r   0validate_schema_for_openai.<locals>.__annotate__|   s     ! !3 !4 !r   c                   < \        V \        4      '       g   R # \        V 4      pVS9   d   R # SP                  V4       RV 9   d   SP	                  V4       R # V P                  R4      R8X  d7   RV 9  d0   RV 9  d)   V P                  R4      RJ d   SP	                  V4       R# V P                  4        F  p\        V\        4      '       d,   RV9  d%   S! V4      '       d   SP	                  V4        R# KD  \        V\        4      '       g   K\  V FG  p\        V\        4      '       g   K  RV9  g   K$  S! V4      '       g   K4  SP	                  V4         R# 	  K  	  SP	                  V4       R # )Fr$   r&   r'   r(   patternPropertiesr)   T)r+   r,   r.   r/   r0   r   valuesr-   )r!   r4   r9   r3   has_invalid_structurer?   s   &   r   rM   9validate_schema_for_openai.<locals>.has_invalid_structure|   s%   #t$$CWFS=OOF#GGFOx'#s*GG*+t3OOF#ZZ\E%&&6+>(//OOF+ 0 E4((!D!$--&2D066#OOF3#'	 " " 	r   rA   )r   rM   r?   s   &@@r   validate_schema_for_openairO   m   s9     FD11eG! !F %V,,,r   a  Schema contains invalid structure for OpenAI: object type with no 'properties' defined but 'additionalProperties: true' (schema-less dictionary not supported by OpenAI). Please define specific properties for your object. Note: Recursive schemas using '$ref' are supported.Nc          
          V ^8  d   QhR\         R\        R\        \        \         3,          R\        \        ,          R\
        /# )r	   r!   target_def_namer6   r?   r   )r   r   r   r   rB   rF   )r   s   "r   r   r      s?     0 0 0s 0$sCx. 0[cdg[h 0tx 0r   c                   V '       d   \        V \        \        34      '       g   R# Vf   \        4       p^ RIpVP                  V R\        R7      pWS9   d   R# VP                  V4        \        V \        4      '       d   RV 9   d   \        V R,          \        4      '       d   V R,          P                  R4      p\        V4      ^8  dj   V^ ,          R8X  d\   V^,          R8X  dN   VR	,          pWq8X  d    VP                  V4       R# Wr9   d%   \        W',          WV4      VP                  V4       # V P                  4        F)  p\        WW#4      '       g   K   VP                  V4       R# 	  ME\        V \        4      '       d0   V  F)  p	\        WW#4      '       g   K   VP                  V4       R# 	  VP                  V4       R#   TP                  T4       i ; i)
aU  
Check if an object contains a recursive reference to a specific definition.

Args:
    obj: Object to check
    target_def_name: Name of the definition to check for recursion
    defs: Dictionary of definitions
    visited: Set of visited object keys to detect cycles
    
Returns:
    True if recursive reference is found, False otherwise
FNT)	sort_keysdefaultr$   /#r%   )r+   r,   r-   rB   jsondumpsr   r/   splitlenr0   _contains_recursive_refrL   )
r!   rQ   r6   r?   rX   obj_keyref_pathdef_namer9   r3   s
   &&&&      r   r\   r\      s    jtTl33%jjcj:GKK!c4  }CK!=!=v;,,S1x=A%(1+*<!PWAW'|H2# 	   '6t~^ef 	  *54QQ 	  & T""*4$PP 	  
 	  	 s1   +BG G 6"G G 1-G #G 7G Gc                R    V ^8  d   QhR\         \        \        3,          R\        /# )r	   r6   r   )r   r   r   rF   )r   s   "r   r   r      s"      4S> d r   c                v    V '       g   R# V P                  4        F  w  r\        W!V 4      '       g   K   R# 	  R# )z
Check if $defs contain circular references.

Args:
    defs: Dictionary of definitions to check
    
Returns:
    True if circular references are found, False otherwise
FT)r2   r\   )r6   r_   	def_values   &  r   _check_for_circular_defsrc      s2     #zz|"9==  , r   c          
          V ^8  d   QhR\         R\        \        \         3,          R\        \        ,          R\
        R\         /# )r	   r!   r6   r?   depthr   )r   r   r   r   rB   int)r   s   "r   r   r      s=     0 0c 0c3h 0(3- 0WZ 0cf 0r   c           
        V '       d$   \        V \        \        34      '       d   V^
8  d   V # Vf   \        4       p\	        V 4      pWB9   d   V # VP                  V4        \        V \        4      '       Ed   RV 9   d   \        V R,          \        4      '       d   V R,          P                  R4      p\        V4      ^8  d`   V^ ,          R8X  dR   V^,          R8X  dD   VR,          pWa9   d5   \        \        W,          4      WV^,           4      VP                  V4       # V VP                  V4       # / pV P                  4        F#  w  rVR8X  d   K  \        WW#^,           4      Wx&   K%  	  VVP                  V4       # \        V \        4      '       d5   V  U
u. uF  p
\        WW#^,           4      NK  	  up
VP                  V4       #  VP                  V4       V # u up
i   TP                  T4       i ; i)a$  
Resolve $ref references in a JSON schema object.

Args:
    obj: Object to resolve references in
    defs: Dictionary of definitions
    visited: Set to track visited objects and prevent infinite recursion
    depth: Current recursion depth
    
Returns:
    Object with resolved references
r$   rU   rV   r%   rW   )r+   r,   r-   rB   r.   r/   r   rZ   r[   resolve_refsr0   r2   )r!   r6   r?   re   r4   r^   r_   resolvedr8   r9   r3   s   &&&&       r   rh   rh      s    jtTl33urz
%WF
KK c4  }CK!=!=v;,,S1x=A%(1+*<!PWAW'|H'+D,@$QVYZQZ[ 	  	 H!iik
'> ,U'19 M *  		 T""MPQSTLWai@SQ 		 # 	J R 	s1   !B0G% #G% 6:G% G% G 8G%  G% %G8c                0    V ^8  d   QhR\         R\        /# r   rE   )r   s   "r   r   r   #  s        C  D  r   c                (   V '       d   \        V \        4      '       g   R# ^ RIpVP                  V 4      pRV9   ;'       g    RV9   ;'       g    RV9   p\	        V P                  R4      ;'       g    V P                  R4      4      pT;'       g    T# )z
Detect if a schema contains recursive references.

Args:
    schema: Schema to analyze
    
Returns:
    True if schema has recursive patterns, False otherwise
FN"$ref"#/$defs/z#/definitions/r%   definitions)r+   r,   rX   rY   rF   r   )r   rX   schema_stringhas_refshas_defss   &    r   detect_recursive_schemarr   #  s     FD11JJv&MM! 	* 	*m#	* 	*M) 
 FJJw'DD6::m+DEHxr   c                R    V ^8  d   QhR\         R\        \        \        3,          /# r   r   r   r   )r   s   "r   r   r   <  s&     C CC C4S> Cr   c                X    V '       g   RRRR/# \        V 4      '       d   RRRR/# RRRR/# )z
Select appropriate model based on schema complexity.

Args:
    schema: Schema to analyze
    
Returns:
    Dict with modelName and reason
	modelNamezgpt-4o-minireason	no_schemazgpt-4orecursive_schema_detectedsimple_schema)rr   )r   s   &r   select_model_for_schemar{   <  s@     ]HkBBv&&Xx1LMM/BBr   c                h    V ^8  d   QhR\         R\        \        \        \         3,          ,          /# r   )r   r   r   r   )r   s   "r   r   r   O  s'     8 8c 8htCH~&> 8r   c                J    \        V R4      '       d,   \        V P                  4      '       d   V P                  4       # \        V R4      '       dn   \        V P                  4      '       dS   \	        V P
                  RR4      p\        V4      '       d   V P
                  P                  4       # V P                  4       # \        V R4      '       d,   \        V P                  4      '       d   V P                  4       # \        V R4      '       dn   \        V P                  4      '       dS   \	        V P
                  RR4      p\        V4      '       d   V P
                  P                  4       # V P                  4       # \        T \        4      '       d   T # R#   \         d     L'i ; i)z}
Normalize a schema object which may be a dict, Pydantic BaseModel subclass,
or a Pydantic model instance into a plain dict.
model_json_schema
model_dumpNr   r,   )
hasattrcallabler~   r   getattr	__class__r   r,   	Exceptionr+   )r   mjsschs   &  r   _normalize_schemar   O  s@   
6.//HV=U=U4V4V++--6<((Xf6G6G-H-H&**,?FC}}''99;;$$&&68$$&--)@)@==?"66""x'<'<&**Hd;C}}''..00;;=   --6747  s0   <F A.F .F ><F ;A.F *F F"!F"c                R    V ^8  d   QhR\         R\        \        \         3,          /# r	   
format_objr   rt   )r   s   "r   r   r   p  s&     C Cc Cd38n Cr   c                z   \        V \        4      '       g   \        R4      hV P                  R4      R8w  d   \        R4      hV P                  R4      p\        V 4      pVEe6   \	        V4      pVEe&   \        V\        4      '       d   VP                  R/ 4      p^ RIpVP                  V4      pVP                  R4      ;'       g    RV9   ;'       g    R	V9   pV'       d[    \        W44      pVP                  V4      p	RV	9   ;'       g    R	V	9   p
V
'       g#   Tp\        V\        4      '       d   RV9   d   VR M, \        W44      p\        V\        4      '       d   RV9   d   VR \        V4      p\        V4      '       g   \        \        4      hWR&   V#   \         d     L>i ; i  \         d     LOi ; i)
z
Validate and prepare json format object.

Args:
    format_obj: Format object that should be json type
    
Returns:
    Validated json format dict
    
Raises:
    ValueError: If json format is missing required fields
Hjson format must be an object with 'type', 'prompt', and 'schema' fieldsr&   rX   z!json format must have type='json'r   Nr%   rl   rm   )r+   r,   
ValueErrorr   r   rX   rY   rh   r   rC   rO   OPENAI_SCHEMA_ERROR_MESSAGE)r   r   r5   normalized_schemar6   rX   ro   has_any_refsresolved_schemaresolved_stringhas_remaining_refsopenai_normalized_schemas   &           r   _validate_json_formatr   p  s    j$''cdd~~f'<== ^^H%Fj!J-f5(+T22(,,Wb9 $

+< =%))'2 0 0-0 0-/   *67H*O*.**_*E-5-H-i-iJZiLi*10?-)*;TBBwRcGc$5g$>,89J,Q)%&7>>7N_C_ 1' :
 (CCT'U$-.FGG !<==#;x % %  % s0   %'F F "F ?+F, F)(F),F:9F:c                R    V ^8  d   QhR\         R\        \        \         3,          /# r   rt   )r   s   "r   r   r     s"      s tCH~ r   c                    \        V \        4      '       g   \        R4      h\        V P                  R4      \        4      '       d   V R,          P                  4       '       g   \        R4      hV # )z
Validate and prepare query format object.

Args:
    format_obj: Format object that should be query type

Returns:
    Validated query format dict

Raises:
    ValueError: If query format is missing required 'prompt' field
>query format must be an object with 'type' and 'prompt' fieldspromptz1query format requires a non-empty 'prompt' string)r+   r,   r   r   r   strip)r   s   &r   _validate_query_formatr     sX     j$''YZZjnnX.44Jx<P<V<V<X<XLMMr   c                \    V ^8  d   QhR\         \        ,          R\         \        ,          /# r	   optionsr   )r   r   )r   s   "r   r   r     s$      Xm%< -AX r   c                    V f   R# V P                   e   V P                   ^ 8:  d   \        R4      hV P                  e   V P                  ^ 8  d   \        R4      hV # )z
Validate and normalize scrape options.

Args:
    options: Scraping options to validate
    
Returns:
    Validated options or None
    
Raises:
    ValueError: If options are invalid
NzTimeout must be positivezwait_for must be non-negative)timeoutr   wait_for)r   s   &r   validate_scrape_optionsr     s[      "w!';344 #(8(81(<899Nr   c                ~    V ^8  d   QhR\         \        ,          R\         \        \        \        3,          ,          /# r   )r   r   r   r   r   )r   s   "r   r   r     s1     z zH]$; zcSVh@X zr   c                   V f   R# \        V 4      pVf   R# RRRRRRRRRRR	RR
RRR/pVP                  RR7      pVP                  4        F  w  rEWC9  g   K  WSV&   K  	  / pRRRRRRRRRRRRRRRRR	RRRR
R/pVP                  4        F   w  rW9   g   K  VP                  V4      Wi&   K"  	  VP                  4        E	Fw  w  rVf   K  V
R8X  d)   \	        V4      P                  4       ;'       g    RVR&   K;  V
R8X  Ed   . p\        V RR4      p\        V\        4      '       Edy   VP                  '       Edo   VP                   EF]  p\        V\        4      '       dA   VR8X  d   \        R 4      hVR!8X  d   \        R"4      hVP                  \        V4      4       KZ  \        V\        4      '       Ed)   VP                  R#4      '       d   \        VP                  R#4      4      MRpVR8X  d%   \        / VCR#R/C4      pVP                  V4       K  VR!8X  d   VP                  \!        V4      4       K  VR$8X  dp   / VCR#R$/CpR%V9   d   VP                  R%4      VR&&   VP                  R'4      p\#        VR(4      '       d   VP                  RR7      VR'&   VP                  V4       EKh  R#V9   d   T;'       g
    VR#,          VR#&   VP                  V4       EK  \#        VR#4      '       d   VP$                  R8X  d,   VP                  \        VP                  4       4      4       EK  VP$                  R!8X  d.   VP                  \!        VP                  RR7      4      4       EK%  VP                  \        VP$                  4      4       EKL  VP                  V4       EK`  	  VP&                  '       d   VP                  R)4       VP(                  '       d   VP                  R*4       VP*                  '       d   VP                  R+4       VP,                  '       d   VP                  R,4       VP.                  '       d   VP                  R-4       VP0                  '       d   VP                  R$4       VP2                  '       d   VP                  R.4       EM7\        V\4        4      '       Ed   V EF  p\        V\        4      '       dA   VR8X  d   \        R 4      hVR!8X  d   \        R"4      hVP                  \        V4      4       KZ  \        V\        4      '       Ed)   VP                  R#4      '       d   \        VP                  R#4      4      MRpVR8X  d%   \        / VCR#R/C4      pVP                  V4       K  VR!8X  d   VP                  \!        V4      4       K  VR$8X  dp   / VCR#R$/CpR%V9   d   VP                  R%4      VR&&   VP                  R'4      p\#        VR(4      '       d   VP                  RR7      VR'&   VP                  V4       EKh  R#V9   d   T;'       g
    VR#,          VR#&   VP                  V4       EK  \#        VR#4      '       EdA   VP$                  R8X  d,   VP                  \        VP                  4       4      4       EK  VP$                  R$8X  d   R#R$/p\        VR%R4      e   VP6                  VR&&   \        VR/R4      e   VP8                  VR/&   \        VR'R4      pVe*   \#        VR(4      '       d   VP                  RR7      MTVR'&   VP                  V4       EK  VP$                  R!8X  d.   VP                  \!        VP                  RR7      4      4       EK  VP                  \        VP$                  4      4       EK  VP                  V4       EK   	  M V F  pVP                  V4       K  	  V'       d   WR&   EK'  EK*  V
R08X  d   . pV F  p\        V\        4      '       dC   / pVP                  4        F  w  ppVR%8X  d   VVR&&   K  VVV&   K  	  VP                  V4       K[  VP                  RR7      p/ pVP                  4        F  w  ppVR%8X  d   VVR&&   K  VVV&   K  	  VP                  V4       K  	  VVR0&   EK  V
R18X  d   . pV F  p\        V\        4      '       d   VP                  V4       K,  \        V\        4      '       d:   \        V4      pR2V9   d   VP                  R24      VR3&   VP                  V4       K{  VP                  RR7      pR2V9   d   VP                  R24      VR3&   VP                  V4       K  	  VVR1&   EK  V
R48X  d6   \        V\        4      '       d   WR4&   EK  VP                  RR7      VR4&   EK  V
R58X  ds   \        V\        4      '       d/   R6VR6,          R7VP                  R8VP                  R7R4      4      /pM&R6VP<                  R7\        VR8\        VR7R4      4      /pVVR5&   E	Ks  WV
&   E	Kz  	  V#   \:         d     ELti ; i)9z
Prepare ScrapeOptions for API submission with manual snake_case to camelCase conversion.

Args:
    options: ScrapeOptions to prepare
    
Returns:
    Dictionary ready for API submission or None if options is None
Nonly_main_contentTmobileFskip_tls_verificationremove_base64_images	fast_mode	block_adsmax_agei  store_in_cache)exclude_noneinclude_tagsincludeTagsexclude_tagsexcludeTagsonlyMainContentr   waitForskipTlsVerificationremoveBase64ImagesfastModeuse_mockuseMockblockAdsstoreInCachemaxAgeintegrationformatsrX   r   queryr   r&   
screenshot	full_pagefullPageviewportr   markdownhtmlr   summarylinksr   qualityactionsparsers	max_pagesmaxPageslocationprofilenamesaveChangessave_changes)r   r   r2   r1   r   r   r   r+   r   r   r   appendr   r,   r   r   r   r   r&   r   r   r   r   r   r   r   r-   r   r   	TypeErrorr   )r   validated_optionsdefault_valuesoptions_datar<   default_valuescrape_datafield_mappings
snake_case
camel_caser8   r9   converted_formatsoriginal_formatsfmtfmt_typevalidated_jsonr5   vpconverted_actionsactionconverted_action
action_keyaction_valueaction_dataconverted_parsersparserparser_dataprofile_datas   &                            r   prepare_scrape_optionsr     s	     08  	T%UT8$	N %//T/BL !/ 4 4 6$"/ !7 K 	.I!6 4ZIZ.8N #1"6"6"8
%&2&6&6z&BK# #9
 #((*
m#.1%j.>.>.@.H.HDM*i/1! $+7It#D .>>'///#3#;#;C)#s33#&&=*45  +A  %A#&'>*45u*v$v 1 8 89OPS9T U!+C!6!6VYV]V]^dVeVe+A#''&/+Rko#+v#55JKbcKbSY[aKb5cN$5$<$<^$L%-%8$5$<$<=STW=X$Y%-%=1NC1N1NJ'2j'@AKP[A\
:(>)3
)CB'.r<'@'@AC\`Aa
:(>$5$<$<Z$H'-}6>6M6M#f+F$5$<$<S$A!(f!5!5#&88v#5$5$<$<=RSVSaSaSc=d$e%(XX%8$5$<$<=STWTbTbptTbTu=v$w$5$<$<=STWT\T\=]$^ 1 8 8 =I $<N (000)00<',,,)008'000)00;'///)00;'---)009'222)00>'777)001AB   0$77/%c3//"f}&01{&| |"g~&01q&r r-445KC5PQ'T22RURYRYZ`RaRa'=cggfo'NgkH'611FG^#G^vW]G^1_ 1 8 8 H!)W!4 1 8 89OPS9T U!)\!9-J-JV\-J
#.*#<=G^^K=XJz$:%/^^J%?#*2|#<#<=?]]X\]=]Jz$: 1 8 8 D#)S=2:2I2Ic&kCK 1 8 8 =$S&11"xx61 1 8 89Ns~~O_9` a!$\!9.4l-C
#*3T#B#N=@]]Jz$:#*3	4#@#L<?KKJy$9%,S*d%C#%>ahikmyazazR]]X\]=]  ACJz$: 1 8 8 D!$W!4 1 8 89OPSP^P^lpP^Pq9r s 1 8 89OPSPXPX9Y Z-44S9Y  0^#(C-44S9 $)
 %->	* %	!$&!#F!&$//+-(8>4J)[8?K 0 <?K 0 <	 9G
 *001AB '-&7&7T&7&J+-(8C8I8I8K4J)[8?K 0 <?K 0 <	 9L
 *001AB' $( *;I&	!$&!#F!&#..)008#FD11&*6l&+56Aook6RK
3)00=&,&7&7T&7&J&+56Aook6RK
3)00= $ *;I&
"eT**.3
+.3.>.>D.>.QK
+	!eT**f%uyy=Z^A_'`$L 

%wungeUbdhFi'j$L *6I& $)C w +z G % s   =h==ii)N)N    )__doc__typingr   r   r   r   typesr   r   r   rC   rO   r   r\   rc   rh   rr   r{   r   r   r   r   r    r   r   <module>r      sk    - , 06$O$d2-lm 0f(0f 2C&8BCL,6zr   