code: def add_implicit_values(json_ai: JsonAI) -> JsonAI:
      """
      To enable brevity in writing, auto-generate the "unspecified/missing" details required in the ML pipeline.
  
      :params: json_ai: ``JsonAI`` object that describes the ML pipeline that may not have every detail fully specified.
  
      :returns: ``JSONAI`` object with all necessary parameters that were previously left unmentioned filled in.
      """
      problem_definition = json_ai.problem_definition
      tss = problem_definition.timeseries_settings
      is_ts = tss.is_timeseries
      mixers = json_ai.model["args"]["submodels"]
  
      # Add implicit ensemble arguments
      param_pairs = {
          "target": json_ai.model["args"].get("target", "$target"),
          "data": json_ai.model["args"].get(
              "data", "encoded_test_data"
          ),
          "mixers": json_ai.model["args"].get("mixers", "$mixers"),
          "fit": json_ai.model["args"].get("fit", True),
          "args": json_ai.model["args"].get("args", "$pred_args"),
          "accuracy_functions": json_ai.model["args"].get(
              "accuracy_functions", "$accuracy_functions"
          ),
          "ts_analysis": json_ai.model["args"].get(
              "ts_analysis", "self.ts_analysis" if is_ts else None
          ),
          "dtype_dict": json_ai.model["args"].get(
              "dtype_dict", "$dtype_dict"
          ),
      }
      ensemble_cls = getattr(
          lightwood.ensemble, json_ai.model["module"]
      )
      filtered_params = {}
      for p_name, p_value in param_pairs.items():
          _add_cls_kwarg(ensemble_cls, filtered_params, p_name, p_value)
  
      json_ai.model["args"] = filtered_params
      json_ai.model["args"]["submodels"] = mixers  # add mixers back in
  
      # Add implicit mixer arguments
      for i in range(len(mixers)):
          if not mixers[i].get("args", False):
              mixers[i]["args"] = {}
  
          if mixers[i]["module"] == "Unit":
              continue
  
          # common
          mixers[i]["args"]["target"] = mixers[i]["args"].get(
              "target", "$target"
          )
          mixers[i]["args"]["dtype_dict"] = mixers[i]["args"].get(
              "dtype_dict", "$dtype_dict"
          )
          mixers[i]["args"]["stop_after"] = mixers[i]["args"].get(
              "stop_after", "$problem_definition.seconds_per_mixer"
          )
  
          # specific
          if mixers[i]["module"] in (
              "Neural",
              "NeuralTs",
              "TabTransformerMixer",
          ):
              mixers[i]["args"]["target_encoder"] = mixers[i][
                  "args"
              ].get("target_encoder", "$encoders[self.target]")
  
              if mixers[i]["module"] in ("Neural", "NeuralTs"):
                  mixers[i]["args"]["net"] = mixers[i]["args"].get(
                      "net",
                      '"DefaultNet"'
                      if not tss.is_timeseries
                      or not tss.use_previous_target
                      else '"ArNet"',
                  )
                  mixers[i]["args"]["search_hyperparameters"] = mixers[
                      i
                  ]["args"].get("search_hyperparameters", True)
                  mixers[i]["args"]["fit_on_dev"] = mixers[i][
                      "args"
                  ].get("fit_on_dev", True)
  
              if mixers[i]["module"] == "NeuralTs":
                  mixers[i]["args"]["timeseries_settings"] = mixers[i][
                      "args"
                  ].get(
                      "timeseries_settings",
                      "$problem_definition.timeseries_settings",
                  )
                  mixers[i]["args"]["ts_analysis"] = mixers[i][
                      "args"
                  ].get("ts_analysis", "$ts_analysis")
  
              if mixers[i]["module"] == "TabTransformerMixer":
                  mixers[i]["args"]["search_hyperparameters"] = mixers[
                      i
                  ]["args"].get("search_hyperparameters", False)
                  mixers[i]["args"]["fit_on_dev"] = mixers[i][
                      "args"
                  ].get("fit_on_dev", False)
  
          elif mixers[i]["module"] in ("LightGBM", "XGBoostMixer"):
              mixers[i]["args"]["input_cols"] = mixers[i]["args"].get(
                  "input_cols", "$input_cols"
              )
              mixers[i]["args"]["target_encoder"] = mixers[i][
                  "args"
              ].get("target_encoder", "$encoders[self.target]")
              mixers[i]["args"]["fit_on_dev"] = mixers[i]["args"].get(
                  "fit_on_dev", True
              )
              mixers[i]["args"]["use_optuna"] = True
  
          elif mixers[i]["module"] == "Regression":
              mixers[i]["args"]["target_encoder"] = mixers[i][
                  "args"
              ].get("target_encoder", "$encoders[self.target]")
  
          elif mixers[i]["module"] == "RandomForest":
              mixers[i]["args"]["target_encoder"] = mixers[i][
                  "args"
              ].get("target_encoder", "$encoders[self.target]")
  
          elif mixers[i]["module"] in (
              "LightGBMArray",
              "XGBoostArrayMixer",
          ):
              mixers[i]["args"]["input_cols"] = mixers[i]["args"].get(
                  "input_cols", "$input_cols"
              )
              mixers[i]["args"]["target_encoder"] = mixers[i][
                  "args"
              ].get("target_encoder", "$encoders[self.target]")
              mixers[i]["args"]["tss"] = mixers[i]["args"].get(
                  "tss", "$problem_definition.timeseries_settings"
              )
              mixers[i]["args"]["ts_analysis"] = mixers[i]["args"].get(
                  "ts_analysis", "$ts_analysis"
              )
              mixers[i]["args"]["fit_on_dev"] = mixers[i]["args"].get(
                  "fit_on_dev", "True"
              )
              mixers[i]["args"]["use_stl"] = mixers[i]["args"].get(
                  "use_stl", "False"
              )
  
          elif mixers[i]["module"] in ("NHitsMixer", "GluonTSMixer"):
              mixers[i]["args"][
                  "horizon"
              ] = "$problem_definition.timeseries_settings.horizon"
              mixers[i]["args"][
                  "window"
              ] = "$problem_definition.timeseries_settings.window"
              mixers[i]["args"]["ts_analysis"] = mixers[i]["args"].get(
                  "ts_analysis", "$ts_analysis"
              )
              problem_definition.fit_on_all = (
                  False  # takes too long otherwise
              )
  
          elif mixers[i]["module"] in (
              "SkTime",
              "ProphetMixer",
              "ETSMixer",
              "ARIMAMixer",
          ):
              mixers[i]["args"]["ts_analysis"] = mixers[i]["args"].get(
                  "ts_analysis", "$ts_analysis"
              )
              if "horizon" not in mixers[i]["args"]:
                  mixers[i]["args"][
                      "horizon"
                  ] = "$problem_definition.timeseries_settings.horizon"
  
              # enforce fit_on_all if this mixer is specified
              problem_definition.fit_on_all = True
  
      # encoder checks
      for name in json_ai.encoders:
          if name not in json_ai.dependency_dict:
              json_ai.dependency_dict[name] = []
  
      # filter arguments for included encoders (custom encoders will skip the check)
      for col, enc_dict in json_ai.encoders.items():
          filtered_kwargs = {}
          if hasattr(lightwood.encoder, enc_dict["module"]):
              encoder_cls = getattr(
                  lightwood.encoder, enc_dict["module"]
              )
              for k, v in enc_dict["args"].items():
                  _add_cls_kwarg(encoder_cls, filtered_kwargs, k, v)
              json_ai.encoders[col]["args"] = filtered_kwargs
  
      # Add "hidden" fields
      hidden_fields = {
          "cleaner": {
              "module": "cleaner",
              "args": {
                  "pct_invalid": "$problem_definition.pct_invalid",
                  "identifiers": "$identifiers",
                  "data": "data",
                  "dtype_dict": "$dtype_dict",
                  "target": "$target",
                  "mode": "$mode",
                  "imputers": "$imputers",
                  "timeseries_settings": "$problem_definition.timeseries_settings.to_dict()",
                  "anomaly_detection": "$problem_definition.anomaly_detection",
              },
          },
          "splitter": {
              "module": "splitter",
              "args": {
                  "tss": "$problem_definition.timeseries_settings.to_dict()",
                  "data": "data",
                  "seed": "$problem_definition.seed_nr",
                  "target": "$target",
                  "dtype_dict": "$dtype_dict",
                  "pct_train": 0.8,
                  "pct_dev": 0.1,
                  "pct_test": 0.1,
              },
          },
          "analyzer": {
              "module": "model_analyzer",
              "args": {
                  "stats_info": "$statistical_analysis",
                  "pdef": "$problem_definition",
                  "accuracy_functions": "$accuracy_functions",
                  "predictor": "$ensemble",
                  "data": "encoded_test_data",
                  "train_data": "encoded_train_data",
                  "target": "$target",
                  "dtype_dict": "$dtype_dict",
                  "analysis_blocks": "$analysis_blocks",
                  "ts_analysis": "$ts_analysis" if is_ts else None,
              },
          },
          "explainer": {
              "module": "explain",
              "args": {
                  "problem_definition": "$problem_definition",
                  "stat_analysis": "$statistical_analysis",
                  "data": "data",
                  "encoded_data": "encoded_data",
                  "predictions": "df",
                  "runtime_analysis": "$runtime_analyzer",
                  "ts_analysis": "$ts_analysis" if is_ts else None,
                  "target_name": "$target",
                  "target_dtype": "$dtype_dict[self.target]",
                  "explainer_blocks": "$analysis_blocks",
                  "pred_args": "$pred_args",
              },
          },
          "analysis_blocks": [
              {
                  "module": "ICP",
                  "args": {
                      "fixed_significance": None,
                      "confidence_normalizer": False,
                  },
              },
              {
                  "module": "AccStats",
                  "args": {"deps": ["ICP"]},
              },
              {
                  "module": "ConfStats",
                  "args": {"deps": ["ICP"]},
              },
              {
                  "module": "PermutationFeatureImportance",
                  "args": {"deps": ["AccStats"]},
              },
          ]
          if problem_definition.use_default_analysis
          else [],
          "timeseries_transformer": {
              "module": "transform_timeseries",
              "args": {
                  "timeseries_settings": "$problem_definition.timeseries_settings",
                  "data": "data",
                  "dtype_dict": "$dtype_dict",
                  "target": "$target",
                  "mode": "$mode",
                  "pred_args": "$pred_args",
              },
          },
          "timeseries_analyzer": {
              "module": "timeseries_analyzer",
              "args": {
                  "timeseries_settings": "$problem_definition.timeseries_settings",
                  "data": "data",
                  "dtype_dict": "$dtype_dict",
                  "target": "$target",
              },
          },
      }
  
      for field_name, implicit_value in hidden_fields.items():
          _populate_implicit_field(
              json_ai, field_name, implicit_value, tss.is_timeseries
          )
  
      # further consolidation
      to_inspect = ["analysis_blocks"]
      consolidation_methods = {
          "analysis_blocks": _consolidate_analysis_blocks
      }
      for k in to_inspect:
          method = consolidation_methods[k]
          setattr(json_ai, k, method(json_ai, k))
  
      return json_ai
  
file_path: lightwood/lightwood/api/json_ai.py
imports: import inspect
  from type_infer.dtype import dtype
  from type_infer.base import TypeInformation
  from dataprep_ml import StatisticalAnalysis
  from lightwood.helpers.templating import _consolidate_analysis_blocks, _add_cls_kwarg
  from lightwood.helpers.constants import IMPORTS, IMPORT_EXTERNAL_DIRS
  from lightwood.api.types import JsonAI, ProblemDefinition
  import lightwood.ensemble
  import lightwood.encoder
label_desc: Use image node_id 5 for calling a global function with example usage: add_implicit_values(json_ai) and returns: json_ai