
    i:                        U d Z ddlmZmZmZ ddlmZmZmZm	Z	m
Z
mZmZ ddlmZmZmZmZmZmZmZmZmZ ddlmZ dedeeef   fdZ G d	 d
e      Ze G d de             ZdddZe G d de             Ze G d de             ZeddeddedddZ eeeeef   f   e!d<   dedee   fdZ"deeee   f   fdZ#deeeeef   f   fdZ$ ede      Z%e G d  d!e             Z&e G d" d#e             Z'e G d$ d%e             Z(y&)'zShared dynamic configuration classes for both node and edge level execution.

This module contains the base classes used by both node-level and edge-level
dynamic execution configurations to avoid circular imports.
    )	dataclassfieldsreplace)AnyClassVarDictMappingOptionalTypeTypeVar)	
BaseConfigChildKeyConfigErrorConfigFieldSpecextend_pathoptional_booloptional_strrequire_mappingrequire_str)enum_options_from_valuesconfigreturnc                     i }t        |       D ]5  }|j                  dk(  rt        | |j                        ||j                  <   7 |S )z5Serialize a config to dict, excluding the path field.path)r   namegetattr)r   payload	field_objs      H/Users/bowang/.openclaw/workspace/ChatDev/entity/configs/dynamic_base.py_serialize_configr       sD     GF^	>>V#")&).."A	 $ N    c                   (    e Zd ZdZdefdZdefdZy)SplitTypeConfigz)Base helper class for split type configs.r   c                 .    | j                   j                  S N)	__class____name__selfs    r   display_labelzSplitTypeConfig.display_label%   s    ~~&&&r!   c                     t        |       S r%   )r    r(   s    r   to_external_valuez!SplitTypeConfig.to_external_value(   s     &&r!   N)r'   
__module____qualname____doc__strr*   r   r,    r!   r   r#   r#   "   s    3's ''3 'r!   r#   c                   j    e Zd ZU dZi Zeeeef      e	d<   e
deeef   dz  dedd fd       ZdefdZy)	MessageSplitConfigzConfiguration for message-based splitting.
    
    Each input message becomes one execution unit. No additional configuration needed.
    FIELD_SPECSdataNr   r   c                     | |      S )Nr   r1   )clsr5   r   s      r   	from_dictzMessageSplitConfig.from_dict5   s     ~r!   c                      y)Nmessager1   r(   s    r   r*   z MessageSplitConfig.display_label:   s    r!   )r'   r-   r.   r/   r4   r   r   r0   r   __annotations__classmethodr	   r   r9   r*   r1   r!   r   r3   r3   ,   sd    
 9;K$sO345:WS#X.5  H\  s r!   r3   z3Leave the content unchanged when no match is found.z,Return empty content when no match is found.)passemptyc                      e Zd ZU dZdZeed<   dZeez  dz  ed<   dZ	e
ed<   dZe
ed	<   dZe
ed
<   dZeed<    eddddd       eddddd       edddddd       ed	dddddd       ed
dddddd       edddddddgd e eej%                               ed       d!	      d"Zed#eeef   d$ed%d fd&       Zd%efd'Zy)(RegexSplitConfiga  Configuration for regex-based splitting.
    
    Split content by regex pattern matches. Each match becomes one execution unit.
    
    Attributes:
        pattern: Python regular expression used to split content.
        group: Capture group name or index. Defaults to the entire match (group 0).
        case_sensitive: Whether the regex should be case sensitive.
        multiline: Enable multiline mode (re.MULTILINE).
        dotall: Enable dotall mode (re.DOTALL).
        on_no_match: Behavior when no match is found.
     patternNgroupTcase_sensitiveF	multilinedotallr>   on_no_matchzRegex Patternr0   z0Python regular expression used to split content.r   display_name	type_hintrequireddescriptionzCapture GroupzDCapture group name or index. Defaults to the entire match (group 0).zCase Sensitiveboolz+Whether the regex should be case sensitive.r   rJ   rK   rL   defaultrM   zMultiline Flagz%Enable multiline mode (re.MULTILINE).)r   rJ   rK   rL   rP   rM   advancezDotall FlagzEnable dotall mode (re.DOTALL).zNo Match Behaviorenumr?   z Behavior when no match is found.)preserve_label_case)	r   rJ   rK   rL   rP   rR   rM   enum_optionsrQ   )rC   rD   rE   rF   rG   rH   r5   r   r   c          	      .   t        ||      }t        |d|d      }|j                  d      }d }|Xt        |t              r|}nEt        |t
              r|j                         rt	        |      }n|}nt        dt        |d            t        |d|d      }t        |d	|d      }t        |d
|d      }	t        |d|      xs d}
|
dvrt        dt        |d             | |||dn
t        |      |t        |      nd|	t        |	      nd|
|      S )NrC   Fallow_emptyrD   zgroup must be str or intrE   T)rP   rF   rG   rH   r>   >   r>   r?   z%on_no_match must be 'pass' or 'empty')rC   rD   rE   rF   rG   rH   r   )r   r   get
isinstanceintr0   isdigitr   r   r   r   rN   )r8   r5   r   mappingrC   group_valuegroup_normalizedrE   rF   rG   rH   s              r   r9   zRegexSplitConfig.from_dict   s.   !$-gy$EJkk'*-1"+s+#. K-&&('*;'7$'2$!"<k$PW>XYY&w0@$PTU!';eL	w$F"7M4@JF//E{SWYfGghh"#1#94tN?S)2)>d9oE#)#54<5#
 	
r!   c                 "    d| j                    dS )Nzregex())rC   r(   s    r   r*   zRegexSplitConfig.display_label   s    ~Q''r!   )r'   r-   r.   r/   rC   r0   r<   rD   rZ   rE   rN   rF   rG   rH   r   r   list_NO_MATCH_DESCRIPTIONSkeysr4   r=   r	   r   r9   r*   r1   r!   r   rA   rA   D   sl    GS"E39t"NDItFDK #(J
 !(^
 *!)E
 %)?
 "&9
 ','":1+0023&$(
 
S8Kt !
WS#X. !
 !
AS !
 !
F(s (r!   rA   c                   r    e Zd ZU dZdZeed<   d eddddd      iZe	d	e
eef   d
edd fd       ZdefdZy)JsonPathSplitConfiga   Configuration for JSON path-based splitting.
    
    Split content by extracting array items from JSON using a path expression.
    Each array item becomes one execution unit.
    
    Attributes:
        json_path: Simple dot-notation path to array (e.g., 'items', 'data.results').
    rB   	json_pathz	JSON Pathr0   TzBSimple dot-notation path to array (e.g., 'items', 'data.results').rI   r5   r   r   c                L    t        ||      }t        |d|d      } | ||      S )Nrf   TrV   )rf   r   )r   r   )r8   r5   r   r\   json_path_values        r   r9   zJsonPathSplitConfig.from_dict   s+    !$-%g{DdS_488r!   c                 "    d| j                    dS )Nz
json_path(r`   )rf   r(   s    r   r*   z!JsonPathSplitConfig.display_label   s    DNN+1--r!   N)r'   r-   r.   r/   rf   r0   r<   r   r4   r=   r	   r   r9   r*   r1   r!   r   re   re      st     Is 	_$\
K 9WS#X. 9 9AV 9 9
.s .r!   re   z#Each input message becomes one unit)
config_clssummaryzSplit by regex pattern matcheszSplit by JSON array path)r;   regexrf   _SPLIT_TYPE_REGISTRYr   c                 X    t         j                  |       }|st        d|  d      |d   S )z&Get the config class for a split type.zUnknown split type: Nrj   )rm   rX   r   r   entrys     r   get_split_type_configrq      s5     $$T*E07>>r!   c                  d    t         j                         D  ci c]  \  } }| |d    c}} S c c}} w )z(Iterate over all registered split types.rj   )rm   itemsro   s     r   iter_split_type_registrationsrt      s3    9M9S9S9UV9U+$D%%%9UVVVs   ,c            	          t         j                         D  ci c]  \  } }| d|j                  d      i c}} S c c}} w )z!Iterate over split type metadata.rk   )rm   rs   rX   ro   s     r   iter_split_type_metadatarv      s<    G[GaGaGcdGceD9eii	233Gcddds   :TSplitConfig)boundc                   X    e Zd ZU dZdZeed<   dZedz  ed<    e	dddddd	
       e	ddddd      dZ
edeeee   f   fd       Zedeee	f   f fd       Zedeeef   dz  dedd fd       ZdefdZdefdZdee   dedz  fdZedee   fd       Zedee   fd       Z xZS )SplitConfigzConfiguration for how to split inputs into execution units.
    
    Attributes:
        type: Split strategy type (message, regex, json_path)
        config: Type-specific configuration
    r;   typeNr   z
Split Typer0   Tz;Strategy for splitting inputs into parallel execution unitsrO   zSplit ConfigobjectFz!Type-specific split configurationrI   r{   r   r   c                 |    t               j                         D ci c]  \  }}t        d|      | c}}S c c}}w )Nr   )fieldvalue)rt   rs   r   )r8   r   rj   s      r   child_routeszSplitConfig.child_routes   sG     %B$C$I$I$K
$K j 840*<$K
 	
 
s   8c                 H   t         |          }|j                  d      }|rzt               }t	               }t        |j                               }|D ci c]'  }||j                  |      xs i j                  d      ) }}t        ||t        ||            |d<   |S c c}w )Nr{   rk   )rR   rT   )	superfield_specsrX   rt   rv   ra   rc   r   r   )	r8   specs	type_specregistrationsmetadata
type_namesr   descriptionsr&   s	           r   r   zSplitConfig.field_specs'  s    #%IIf%	9;M/1Hm0023JXbcXbPTD8<<#5#;"@"@"KKXbLc#5j,OE&M
  ds   ,Br5   r   c          	         | | dt        t        |d            |      S t        ||      }t        |d|      xs d}|t        vr8t        dt        t        j                                d| dt        |d            t        |      }|j                  d      }t        |d      }|dk(  r|j                  ||      }n$|t        | d	|      |j                  ||      } | |||      S )
Nr;   r   r7   )r{   r   r   r{   zsplit type must be one of z, got ''z split requires 'config' field)r3   r   r   r   rm   r   ra   rc   rq   rX   r9   )	r8   r5   r   r\   
split_typerj   config_dataconfig_pathr   s	            r   r9   zSplitConfig.from_dict7  s   <I.@kRVX`Fa.bimnn!$-!'648EI
11,T2F2K2K2M-N,OwWaVbbcdD&) 
 +:6
kk(+!$1 "))+K)HF"!ZL0N"OQUVV))+K)HF
6==r!   c                 f    | j                   r| j                   j                         S | j                  S r%   )r   r*   r{   r(   s    r   r*   zSplitConfig.display_labelT  s&    ;;;;,,..yyr!   c                 p    | j                   | j                  r| j                  j                         dS i dS )Nr}   )r{   r   r,   r(   s    r   r,   zSplitConfig.to_external_valueY  s6    II9=dkk335
 	
JL
 	
r!   expected_typec                 H    t        | j                  |      r| j                  S y)z9Return the nested config if it matches the expected type.N)rY   r   )r)   r   s     r   as_split_configzSplitConfig.as_split_config_  s    dkk=1;;r!   c                 d    t        | j                  t              r| j                  j                  S y)z+Get regex pattern if this is a regex split.N)rY   r   rA   rC   r(   s    r   rC   zSplitConfig.patternf  s&     dkk#34;;&&&r!   c                 d    t        | j                  t              r| j                  j                  S y)z+Get json_path if this is a json_path split.N)rY   r   re   rf   r(   s    r   rf   zSplitConfig.json_pathm  s&     dkk#67;;(((r!   )r'   r-   r.   r/   r{   r0   r<   r   r#   r   r4   r=   r   r   r   r   r   r   r	   r   r9   r*   r,   rw   r   propertyr
   rC   rf   __classcell__)r&   s   @r   rz   rz     sY    D#%)FOd")  %U
 "';
K$ 
T(D,<"<= 
 
 Do!56   >WS#X.5 > > > >8s 

3 
T,-? LSWDW  #   8C=  r!   rz   c            	       n    e Zd ZU dZdZeed<   d edddddd      iZe	d	e
eef   d
z  dedd fd       Zy
)MapDynamicConfigzConfiguration for Map dynamic mode (fan-out only).
    
    Map mode is similar to passthrough - minimal config required.
    
    Attributes:
        max_parallel: Maximum concurrent executions
    
   max_parallelMax ParallelrZ   Fz%Maximum number of parallel executionsrO   r5   Nr   r   c                z    |	 | |      S t        ||      }t        |j                  dd            } | ||      S )Nr7   r   r   )r   r   )r   rZ   rX   )r8   r5   r   r\   r   s        r   r9   zMapDynamicConfig.from_dict  s?    <D>!!$-7;;~r:;488r!   )r'   r-   r.   r/   r   rZ   r<   r   r4   r=   r	   r0   r   r9   r1   r!   r   r   r   u  sp     L# 	'?
	K 9WS#X.5 9 9HZ 9 9r!   r   c            	           e Zd ZU dZdZeed<   dZeed<    edddddd	
       edddddd
      dZ	e
deeef   dz  dedd fd       Zy)TreeDynamicConfigzConfiguration for Tree dynamic mode (fan-out and reduce).
    
    Attributes:
        group_size: Number of items per group in reduction
        max_parallel: Maximum concurrent executions per layer
       
group_sizer   r   z
Group SizerZ   Fz*Number of items per group during reductionrO   r   z'Maximum concurrent executions per layer)r   r   r5   Nr   r   c                    |	 | |      S t        ||      }t        |j                  dd            }|dk  rt        dt	        |d            t        |j                  dd            } | |||      S )	Nr7   r   r      zgroup_size must be at least 2r   r   )r   r   r   )r   rZ   rX   r   r   )r8   r5   r   r\   r   r   s         r   r9   zTreeDynamicConfig.from_dict  ss    <D>!!$-\156
>={4Q]?^__7;;~r:;j|$OOr!   )r'   r-   r.   r/   r   rZ   r<   r   r   r4   r=   r	   r0   r   r9   r1   r!   r   r   r     s     JL# &%D
 ('A
K& PWS#X.5 P PH[ P Pr!   r   N))r/   dataclassesr   r   r   typingr   r   r   r	   r
   r   r   entity.configs.baser   r   r   r   r   r   r   r   r   entity.enum_optionsr   r0   r    r#   r3   rb   rA   re   rm   r<   rq   rt   rv   rw   rz   r   r   r1   r!   r   <module>r      s   3 2 H H H
 
 
 9j T#s(^ 'j '   $ B;  t( t( t(n ./ . .F )8
 '3
 *-3 d3S#X./   _(= WtCo1F,F'G W
e$sDcN':"; e
 ~_= n* n nb 9z 9 9< &P
 &P &Pr!   