def _determine_source(model, source,
                      output_names,
                      outputs_as_tensor_or_image_types,
                      output_argument_as_specified_by_user) -> str:
    """
    Infer source (which can be auto) to the precise framework.
    """
    source = source.lower()
    if source not in {"auto", "tensorflow", "pytorch", "milinternal"}:
        raise ValueError(
            f'Unrecognized value of argument "source": {source}. It must be one of ["auto", "tensorflow", "pytorch", "milinternal"].'
        )

    # Determine tensorflow version
    if source == "tensorflow" and _HAS_TF_2:
        return "tensorflow2"

    if source != 'auto':
        return source

    # Determine `auto` source
    if source == "auto" and _HAS_TF_1:
        try:
            loader = TF1Loader(model, outputs=outputs_as_tensor_or_image_types)
            loader._graph_def_from_model(output_names=output_names)
            return "tensorflow"
        except:
            pass

    if source == "auto" and _HAS_TF_2:
        try:
            loader = TF2Loader(model, outputs=outputs_as_tensor_or_image_types)
            loader._graph_def_from_model(output_names=output_names)
            return "tensorflow2"
        except:
            pass

    if source == "auto" and _HAS_TORCH:

        if _HAS_TORCH_EXPORT_API and isinstance(model, ExportedProgram):
            return "pytorch"

        if is_torch_model(model):
            # validate that the outputs passed by the user are of type ImageType/TensorType
            if output_argument_as_specified_by_user is not None and not all(
                [
                    (isinstance(t, InputType) and t.can_be_output())
                    for t in output_argument_as_specified_by_user
                ]
            ):
                raise ValueError(
                    '"outputs" must be a list of type ct.TensorType or ct.ImageType '
                    "for pytorch conversion"
                )
            return "pytorch"

    if source == "auto" and isinstance(model, Program):
        return "milinternal"

    msg = (
        "Unable to determine the type of the model, i.e. the source framework. "
        'Please provide the value of argument "source", from one of '
        '["tensorflow", "pytorch", "milinternal"]. Note that model conversion requires the '
        "source package that generates the model. Please make sure you have "
        "the appropriate version of source package installed. E.g., if you're "
        "converting model originally trained with TensorFlow 1.14, make sure "
        "you have `tensorflow==1.14` installed."
    )
    raise ValueError(msg)

    Infer source (which can be auto) to the precise framework.
    
coremltools/converters/_converters_entry.py