@@ -612,8 +612,8 @@ class ConfigurationWithCommandsParams(CoreModel):
612612
613613 @root_validator
614614 def check_image_or_commands_present (cls , values ):
615- # If replica_groups is present, skip validation - commands come from replica groups
616- replica_groups = values .get ("replica_groups " )
615+ # If replicas is present, skip validation - commands come from replica groups
616+ replica_groups = values .get ("replicas " )
617617 if replica_groups :
618618 return values
619619
@@ -838,25 +838,25 @@ class ServiceConfigurationParams(CoreModel):
838838 SERVICE_HTTPS_DEFAULT
839839 )
840840 auth : Annotated [bool , Field (description = "Enable the authorization" )] = True
841- replicas : Annotated [
842- Range [int ],
843- Field (
844- description = "The number of replicas. Can be a number (e.g. `2`) or a range (`0..4` or `1..8`). "
845- "If it's a range, the `scaling` property is required"
846- ),
847- ] = Range [int ](min = 1 , max = 1 )
848- scaling : Annotated [
849- Optional [ScalingSpec ],
850- Field (description = "The auto-scaling rules. Required if `replicas` is set to a range" ),
851- ] = None
841+ # replicas: Annotated[
842+ # Range[int],
843+ # Field(
844+ # description="The number of replicas. Can be a number (e.g. `2`) or a range (`0..4` or `1..8`). "
845+ # "If it's a range, the `scaling` property is required"
846+ # ),
847+ # ] = Range[int](min=1, max=1)
848+ # scaling: Annotated[
849+ # Optional[ScalingSpec],
850+ # Field(description="The auto-scaling rules. Required if `replicas` is set to a range"),
851+ # ] = None
852852 rate_limits : Annotated [list [RateLimit ], Field (description = "Rate limiting rules" )] = []
853853 probes : Annotated [
854854 list [ProbeConfig ],
855855 Field (description = "List of probes used to determine job health" ),
856856 ] = []
857857
858- replica_groups : Annotated [
859- Optional [List [ReplicaGroup ]],
858+ replicas : Annotated [
859+ Optional [Union [ Range [ int ], List [ReplicaGroup ], int , str ]],
860860 Field (
861861 description = (
862862 "List of replica groups. Each group defines replicas with shared configuration "
@@ -882,15 +882,15 @@ def convert_model(cls, v: Optional[Union[AnyModel, str]]) -> Optional[AnyModel]:
882882 return OpenAIChatModel (type = "chat" , name = v , format = "openai" )
883883 return v
884884
885- @validator ("replicas" )
886- def convert_replicas (cls , v : Range [int ]) -> Range [int ]:
887- if v .max is None :
888- raise ValueError ("The maximum number of replicas is required" )
889- if v .min is None :
890- v .min = 0
891- if v .min < 0 :
892- raise ValueError ("The minimum number of replicas must be greater than or equal to 0" )
893- return v
885+ # @validator("replicas")
886+ # def convert_replicas(cls, v: Range[int]) -> Range[int]:
887+ # if v.max is None:
888+ # raise ValueError("The maximum number of replicas is required")
889+ # if v.min is None:
890+ # v.min = 0
891+ # if v.min < 0:
892+ # raise ValueError("The minimum number of replicas must be greater than or equal to 0")
893+ # return v
894894
895895 @validator ("gateway" )
896896 def validate_gateway (
@@ -902,53 +902,43 @@ def validate_gateway(
902902 )
903903 return v
904904
905- @root_validator ()
906- def validate_scaling (cls , values ):
907- replica_groups = values .get ("replica_groups" )
908- # If replica_groups are set, we don't need to validate scaling.
909- # Each replica group has its own scaling.
910- if replica_groups :
911- return values
912-
913- scaling = values .get ("scaling" )
914- replicas = values .get ("replicas" )
915- if replicas and replicas .min != replicas .max and not scaling :
916- raise ValueError ("When you set `replicas` to a range, ensure to specify `scaling`." )
917- if replicas and replicas .min == replicas .max and scaling :
918- raise ValueError ("To use `scaling`, `replicas` must be set to a range." )
919- return values
905+ # @root_validator()
906+ # def validate_scaling(cls, values):
907+ # replica_groups = values.get("replica_groups")
908+ # # If replica_groups are set, we don't need to validate scaling.
909+ # # Each replica group has its own scaling.
910+ # if replica_groups:
911+ # return values
912+
913+ # scaling = values.get("scaling")
914+ # replicas = values.get("replicas")
915+ # if replicas and replicas.min != replicas.max and not scaling:
916+ # raise ValueError("When you set `replicas` to a range, ensure to specify `scaling`.")
917+ # if replicas and replicas.min == replicas.max and scaling:
918+ # raise ValueError("To use `scaling`, `replicas` must be set to a range.")
919+ # return values
920920
921921 @root_validator ()
922- def normalize_to_replica_groups (cls , values ):
923- replica_groups = values .get ("replica_groups" )
924- if replica_groups :
925- return values
926-
927- # TEMP: prove we’re here and see the inputs
928- print (
929- "[normalize_to_replica_groups]" ,
930- "commands:" ,
931- values .get ("commands" ),
932- "replicas:" ,
933- values .get ("replicas" ),
934- "resources:" ,
935- values .get ("resources" ),
936- "scaling:" ,
937- values .get ("scaling" ),
938- "probes:" ,
939- values .get ("probes" ),
940- "rate_limits:" ,
941- values .get ("rate_limits" ),
942- )
943- # If replica_groups is not set, we need to normalize the configuration to replica groups.
944- values ["replica_groups" ] = [
922+ def normalize_replicas (cls , values ):
923+ replicas = values .get ("replicas" )
924+ if isinstance (replicas , list ) and len (replicas ) > 0 :
925+ if all (isinstance (item , ReplicaGroup ) for item in replicas ):
926+ return values
927+
928+ # Handle backward compatibility: convert old-style replica config to groups
929+ old_replicas = values .get ("replicas" )
930+ if isinstance (old_replicas , Range ):
931+ replica_count = old_replicas
932+ else :
933+ replica_count = Range [int ](min = 1 , max = 1 )
934+ values ["replicas" ] = [
945935 ReplicaGroup (
946936 name = "default" ,
947- replicas = values . get ( "replicas" ) ,
948- commands = values .get ("commands" ),
937+ replicas = replica_count ,
938+ commands = values .get ("commands" , [] ),
949939 resources = values .get ("resources" ),
950940 scaling = values .get ("scaling" ),
951- probes = values .get ("probes" ),
941+ probes = values .get ("probes" , [] ),
952942 rate_limits = values .get ("rate_limits" ),
953943 )
954944 ]
@@ -975,22 +965,24 @@ def validate_probes(cls, v: list[ProbeConfig]) -> list[ProbeConfig]:
975965 raise ValueError ("Probes must be unique" )
976966 return v
977967
978- @validator ("replica_groups" )
979- def validate_replica_groups (
980- cls , v : Optional [List [ReplicaGroup ]]
981- ) -> Optional [List [ReplicaGroup ]]:
968+ @validator ("replicas" )
969+ def validate_replicas (cls , v : Optional [List [ReplicaGroup ]]) -> Optional [List [ReplicaGroup ]]:
982970 if v is None :
983971 return v
984- if not v :
985- raise ValueError ("`replica_groups` cannot be an empty list" )
986- # Check for duplicate names
987- names = [group .name for group in v ]
988- if len (names ) != len (set (names )):
989- duplicates = [name for name in set (names ) if names .count (name ) > 1 ]
990- raise ValueError (
991- f"Duplicate replica group names found: { duplicates } . "
992- "Each replica group must have a unique name."
993- )
972+ if isinstance (v , (Range , int , str )):
973+ return v
974+
975+ if isinstance (v , list ):
976+ if not v :
977+ raise ValueError ("`replicas` cannot be an empty list" )
978+ # Check for duplicate names
979+ names = [group .name for group in v ]
980+ if len (names ) != len (set (names )):
981+ duplicates = [name for name in set (names ) if names .count (name ) > 1 ]
982+ raise ValueError (
983+ f"Duplicate replica group names found: { duplicates } . "
984+ "Each replica group must have a unique name."
985+ )
994986 return v
995987
996988
0 commit comments