@@ -550,6 +550,17 @@ class CallableModelGenericType(CallableModel, Generic[ContextType, ResultType]):
550550 context and result type will be validated.
551551 """
552552
553+ _context_type : ClassVar [Type [ContextType ]]
554+ _result_type : ClassVar [Type [ResultType ]]
555+
556+ @property
557+ def context_type (self ) -> Type [ContextType ]:
558+ return self ._context_type
559+
560+ @property
561+ def result_type (self ) -> Type [ResultType ]:
562+ return self ._result_type
563+
553564 @model_validator (mode = "wrap" )
554565 def _validate_callable_model_generic_type (cls , m , handler , info ):
555566 from ccflow .base import resolve_str
@@ -561,8 +572,26 @@ def _validate_callable_model_generic_type(cls, m, handler, info):
561572 # Raise ValueError (not TypeError) as per https://docs.pydantic.dev/latest/errors/errors/
562573 if not isinstance (m , CallableModel ):
563574 raise ValueError (f"{ m } is not a CallableModel: { type (m )} " )
564- subtypes = cls .__pydantic_generic_metadata__ ["args" ]
565- if subtypes :
566- TypeAdapter (Type [subtypes [0 ]]).validate_python (m .context_type )
567- TypeAdapter (Type [subtypes [1 ]]).validate_python (m .result_type )
575+
576+ # Extract the generic types from the class definition
577+ generic_base = None
578+ for base in cls .__mro__ [1 :]:
579+ if issubclass (base , CallableModelGenericType ):
580+ generic_base = base
581+ break
582+
583+ if generic_base and generic_base .__pydantic_generic_metadata__ ["args" ]:
584+ # cls is subclass of generic_base which defines the generic types
585+ # so use these as the context and result types
586+ subtypes = generic_base .__pydantic_generic_metadata__ ["args" ]
587+ if len (subtypes ) != 2 :
588+ raise ValueError ("CallableModelGenericType must have exactly two generic type parameters: ContextType and ResultType" )
589+ cls ._context_type = subtypes [0 ]
590+ cls ._result_type = subtypes [1 ]
591+
592+ else :
593+ subtypes = cls .__pydantic_generic_metadata__ ["args" ]
594+ if subtypes :
595+ TypeAdapter (Type [subtypes [0 ]]).validate_python (m .context_type )
596+ TypeAdapter (Type [subtypes [1 ]]).validate_python (m .result_type )
568597 return m
0 commit comments