validmind 2.13.4__tar.gz → 2.13.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. {validmind-2.13.4 → validmind-2.13.6}/PKG-INFO +7 -1
  2. {validmind-2.13.4 → validmind-2.13.6}/pyproject.toml +11 -3
  3. validmind-2.13.6/validmind/__version__.py +1 -0
  4. {validmind-2.13.4 → validmind-2.13.6}/validmind/ai/utils.py +184 -23
  5. {validmind-2.13.4 → validmind-2.13.6}/validmind/api_client.py +183 -13
  6. validmind-2.13.6/validmind/credentials_store.py +179 -0
  7. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/llm/agent_dataset.py +8 -6
  8. {validmind-2.13.4 → validmind-2.13.6}/validmind/errors.py +4 -0
  9. validmind-2.13.6/validmind/oidc_device.py +421 -0
  10. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/AnswerRelevancy.py +2 -3
  11. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/ArgumentCorrectness.py +2 -3
  12. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/Bias.py +2 -3
  13. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/ContextualPrecision.py +2 -3
  14. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/ContextualRecall.py +2 -3
  15. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/ContextualRelevancy.py +2 -3
  16. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/Faithfulness.py +2 -3
  17. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/Hallucination.py +2 -3
  18. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/Summarization.py +2 -3
  19. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/ToolCorrectness.py +2 -3
  20. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/__init__.py +1 -1
  21. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/IQROutliersBarPlot.py +6 -2
  22. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/IQROutliersTable.py +5 -2
  23. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/MissingValues.py +3 -3
  24. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ModelPredictionResiduals.py +2 -2
  25. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ragas/AnswerCorrectness.py +1 -1
  26. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ragas/AspectCritic.py +1 -1
  27. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ragas/ContextEntityRecall.py +1 -1
  28. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ragas/ContextPrecision.py +1 -1
  29. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ragas/ContextPrecisionWithoutReference.py +1 -1
  30. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ragas/ContextRecall.py +1 -1
  31. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ragas/Faithfulness.py +1 -1
  32. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ragas/SemanticSimilarity.py +1 -1
  33. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/FeatureImportance.py +3 -3
  34. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/HyperParametersTuning.py +1 -3
  35. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/MinimumF1Score.py +12 -3
  36. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/PrecisionRecallCurve.py +1 -0
  37. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/ROCCurve.py +1 -0
  38. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/RobustnessDiagnosis.py +3 -3
  39. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/CumulativePredictionProbabilities.py +2 -2
  40. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/PredictionProbabilitiesHistogram.py +2 -2
  41. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/ScorecardHistogram.py +2 -2
  42. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/prompt_validation/ai_powered_test.py +2 -1
  43. {validmind-2.13.4 → validmind-2.13.6}/validmind/utils.py +16 -15
  44. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/dataset/dataset.py +1 -1
  45. validmind-2.13.4/validmind/__version__.py +0 -1
  46. {validmind-2.13.4 → validmind-2.13.6}/.gitignore +0 -0
  47. {validmind-2.13.4 → validmind-2.13.6}/LICENSE +0 -0
  48. {validmind-2.13.4 → validmind-2.13.6}/README.pypi.md +0 -0
  49. {validmind-2.13.4 → validmind-2.13.6}/validmind/__init__.py +0 -0
  50. {validmind-2.13.4 → validmind-2.13.6}/validmind/ai/test_descriptions.py +0 -0
  51. {validmind-2.13.4 → validmind-2.13.6}/validmind/client.py +0 -0
  52. {validmind-2.13.4 → validmind-2.13.6}/validmind/client_config.py +0 -0
  53. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/__init__.py +0 -0
  54. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/classification/__init__.py +0 -0
  55. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/classification/config.json +0 -0
  56. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/classification/customer_churn.py +0 -0
  57. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/classification/datasets/bank_customer_churn.csv +0 -0
  58. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/classification/datasets/taiwan_credit.csv +0 -0
  59. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/classification/taiwan_credit.py +0 -0
  60. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/cluster/digits.py +0 -0
  61. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/credit_risk/__init__.py +0 -0
  62. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/credit_risk/datasets/lending_club_biased.csv.gz +0 -0
  63. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/credit_risk/datasets/lending_club_loan_data_2007_2014_clean.csv.gz +0 -0
  64. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/credit_risk/lending_club.py +0 -0
  65. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/credit_risk/lending_club_bias.py +0 -0
  66. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/llm/__init__.py +0 -0
  67. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/llm/rag/__init__.py +0 -0
  68. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/llm/rag/datasets/rfp_existing_questions_client_1.csv +0 -0
  69. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/llm/rag/datasets/rfp_existing_questions_client_2.csv +0 -0
  70. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/llm/rag/datasets/rfp_existing_questions_client_3.csv +0 -0
  71. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/llm/rag/datasets/rfp_existing_questions_client_4.csv +0 -0
  72. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/llm/rag/datasets/rfp_existing_questions_client_5.csv +0 -0
  73. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/llm/rag/rfp.py +0 -0
  74. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/nlp/__init__.py +0 -0
  75. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/nlp/cnn_dailymail.py +0 -0
  76. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/nlp/datasets/Covid_19.csv +0 -0
  77. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/nlp/datasets/cnn_dailymail_100_with_predictions.csv +0 -0
  78. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/nlp/datasets/cnn_dailymail_500_with_predictions.csv +0 -0
  79. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/nlp/datasets/sentiments_with_predictions.csv +0 -0
  80. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/nlp/twitter_covid_19.py +0 -0
  81. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/__init__.py +0 -0
  82. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/california_housing.py +0 -0
  83. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/california_housing.csv +0 -0
  84. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred/CPIAUCSL.csv +0 -0
  85. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred/CSUSHPISA.csv +0 -0
  86. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred/DRSFRMACBS.csv +0 -0
  87. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred/FEDFUNDS.csv +0 -0
  88. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred/GDP.csv +0 -0
  89. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred/GDPC1.csv +0 -0
  90. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred/GS10.csv +0 -0
  91. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred/GS3.csv +0 -0
  92. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred/GS5.csv +0 -0
  93. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred/MORTGAGE30US.csv +0 -0
  94. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred/UNRATE.csv +0 -0
  95. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred_loan_rates.csv +0 -0
  96. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred_loan_rates_test_1.csv +0 -0
  97. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred_loan_rates_test_2.csv +0 -0
  98. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred_loan_rates_test_3.csv +0 -0
  99. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred_loan_rates_test_4.csv +0 -0
  100. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/fred_loan_rates_test_5.csv +0 -0
  101. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/datasets/leanding_club_loan_rates.csv +0 -0
  102. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/fred.py +0 -0
  103. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/fred_timeseries.py +0 -0
  104. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/generate_california_housing_csv.py +0 -0
  105. {validmind-2.13.4 → validmind-2.13.6}/validmind/datasets/regression/lending_club.py +0 -0
  106. {validmind-2.13.4 → validmind-2.13.6}/validmind/experimental/__init__.py +0 -0
  107. {validmind-2.13.4 → validmind-2.13.6}/validmind/experimental/agents.py +0 -0
  108. {validmind-2.13.4 → validmind-2.13.6}/validmind/html_templates/__init__.py +0 -0
  109. {validmind-2.13.4 → validmind-2.13.6}/validmind/html_templates/content_blocks.py +0 -0
  110. {validmind-2.13.4 → validmind-2.13.6}/validmind/input_registry.py +0 -0
  111. {validmind-2.13.4 → validmind-2.13.6}/validmind/logging.py +0 -0
  112. {validmind-2.13.4 → validmind-2.13.6}/validmind/models/__init__.py +0 -0
  113. {validmind-2.13.4 → validmind-2.13.6}/validmind/models/foundation.py +0 -0
  114. {validmind-2.13.4 → validmind-2.13.6}/validmind/models/function.py +0 -0
  115. {validmind-2.13.4 → validmind-2.13.6}/validmind/models/huggingface.py +0 -0
  116. {validmind-2.13.4 → validmind-2.13.6}/validmind/models/metadata.py +0 -0
  117. {validmind-2.13.4 → validmind-2.13.6}/validmind/models/pipeline.py +0 -0
  118. {validmind-2.13.4 → validmind-2.13.6}/validmind/models/pytorch.py +0 -0
  119. {validmind-2.13.4 → validmind-2.13.6}/validmind/models/r_model.py +0 -0
  120. {validmind-2.13.4 → validmind-2.13.6}/validmind/models/sklearn.py +0 -0
  121. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/__init__.py +0 -0
  122. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/classification/AbsoluteError.py +0 -0
  123. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/classification/BrierScore.py +0 -0
  124. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/classification/CalibrationError.py +0 -0
  125. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/classification/ClassBalance.py +0 -0
  126. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/classification/Confidence.py +0 -0
  127. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/classification/Correctness.py +0 -0
  128. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/classification/LogLoss.py +0 -0
  129. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/classification/OutlierScore.py +0 -0
  130. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/classification/ProbabilityError.py +0 -0
  131. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/classification/Uncertainty.py +0 -0
  132. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/classification/__init__.py +0 -0
  133. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/GEval.py +0 -0
  134. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/PlanAdherence.py +0 -0
  135. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/PlanQuality.py +0 -0
  136. {validmind-2.13.4 → validmind-2.13.6}/validmind/scorers/llm/deepeval/TaskCompletion.py +0 -0
  137. {validmind-2.13.4 → validmind-2.13.6}/validmind/template.py +0 -0
  138. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/__init__.py +0 -0
  139. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/classifier.py +0 -0
  140. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/cluster.py +0 -0
  141. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/embeddings.py +0 -0
  142. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/llm.py +0 -0
  143. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/nlp.py +0 -0
  144. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/parameters_optimization.py +0 -0
  145. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/regression.py +0 -0
  146. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/statsmodels_timeseries.py +0 -0
  147. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/summarization.py +0 -0
  148. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/tabular_datasets.py +0 -0
  149. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/text_data.py +0 -0
  150. {validmind-2.13.4 → validmind-2.13.6}/validmind/test_suites/time_series.py +0 -0
  151. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/__init__.py +0 -0
  152. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/__types__.py +0 -0
  153. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/_store.py +0 -0
  154. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/comparison.py +0 -0
  155. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ACFandPACFPlot.py +0 -0
  156. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ADF.py +0 -0
  157. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/AutoAR.py +0 -0
  158. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/AutoMA.py +0 -0
  159. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/AutoStationarity.py +0 -0
  160. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/BivariateScatterPlots.py +0 -0
  161. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/BoxPierce.py +0 -0
  162. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ChiSquaredFeaturesTable.py +0 -0
  163. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ClassImbalance.py +0 -0
  164. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/DatasetDescription.py +0 -0
  165. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/DatasetSplit.py +0 -0
  166. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/DescriptiveStatistics.py +0 -0
  167. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/DickeyFullerGLS.py +0 -0
  168. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/Duplicates.py +0 -0
  169. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/EngleGrangerCoint.py +0 -0
  170. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/FeatureTargetCorrelationPlot.py +0 -0
  171. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/HighCardinality.py +0 -0
  172. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/HighPearsonCorrelation.py +0 -0
  173. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/IsolationForestOutliers.py +0 -0
  174. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/JarqueBera.py +0 -0
  175. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/KPSS.py +0 -0
  176. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/LJungBox.py +0 -0
  177. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/LaggedCorrelationHeatmap.py +0 -0
  178. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/MissingValuesBarPlot.py +0 -0
  179. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/MutualInformation.py +0 -0
  180. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/PearsonCorrelationMatrix.py +0 -0
  181. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/PhillipsPerronArch.py +0 -0
  182. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ProtectedClassesCombination.py +0 -0
  183. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ProtectedClassesDescription.py +0 -0
  184. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ProtectedClassesDisparity.py +0 -0
  185. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ProtectedClassesThresholdOptimizer.py +0 -0
  186. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/RollingStatsPlot.py +0 -0
  187. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/RunsTest.py +0 -0
  188. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ScatterPlot.py +0 -0
  189. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ScoreBandDefaultRates.py +0 -0
  190. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/SeasonalDecompose.py +0 -0
  191. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ShapiroWilk.py +0 -0
  192. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/Skewness.py +0 -0
  193. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/SpreadPlot.py +0 -0
  194. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TabularCategoricalBarPlots.py +0 -0
  195. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TabularDateTimeHistograms.py +0 -0
  196. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TabularDescriptionTables.py +0 -0
  197. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TabularNumericalHistograms.py +0 -0
  198. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TargetRateBarPlots.py +0 -0
  199. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TimeSeriesDescription.py +0 -0
  200. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TimeSeriesDescriptiveStatistics.py +0 -0
  201. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TimeSeriesFrequency.py +0 -0
  202. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TimeSeriesHistogram.py +0 -0
  203. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TimeSeriesLinePlot.py +0 -0
  204. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TimeSeriesMissingValues.py +0 -0
  205. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TimeSeriesOutliers.py +0 -0
  206. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/TooManyZeroValues.py +0 -0
  207. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/UniqueRows.py +0 -0
  208. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/WOEBinPlots.py +0 -0
  209. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/WOEBinTable.py +0 -0
  210. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/ZivotAndrewsArch.py +0 -0
  211. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/__init__.py +0 -0
  212. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/nlp/CommonWords.py +0 -0
  213. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/nlp/Hashtags.py +0 -0
  214. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/nlp/LanguageDetection.py +0 -0
  215. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/nlp/Mentions.py +0 -0
  216. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/nlp/PolarityAndSubjectivity.py +0 -0
  217. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/nlp/Punctuations.py +0 -0
  218. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/nlp/Sentiment.py +0 -0
  219. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/nlp/StopWords.py +0 -0
  220. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/nlp/TextDescription.py +0 -0
  221. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/nlp/Toxicity.py +0 -0
  222. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/data_validation/nlp/__init__.py +0 -0
  223. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/decorator.py +0 -0
  224. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/load.py +0 -0
  225. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/BertScore.py +0 -0
  226. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/BleuScore.py +0 -0
  227. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ClusterSizeDistribution.py +0 -0
  228. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ContextualRecall.py +0 -0
  229. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/FeaturesAUC.py +0 -0
  230. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/MeteorScore.py +0 -0
  231. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ModelMetadata.py +0 -0
  232. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/RegardScore.py +0 -0
  233. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/RegressionResidualsPlot.py +0 -0
  234. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/RougeScore.py +0 -0
  235. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/TimeSeriesPredictionWithCI.py +0 -0
  236. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/TimeSeriesPredictionsPlot.py +0 -0
  237. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/TimeSeriesR2SquareBySegments.py +0 -0
  238. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/TokenDisparity.py +0 -0
  239. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ToxicityScore.py +0 -0
  240. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/__init__.py +0 -0
  241. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/ClusterDistribution.py +0 -0
  242. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/CosineSimilarityComparison.py +0 -0
  243. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/CosineSimilarityDistribution.py +0 -0
  244. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/CosineSimilarityHeatmap.py +0 -0
  245. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/DescriptiveAnalytics.py +0 -0
  246. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/EmbeddingsVisualization2D.py +0 -0
  247. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/EuclideanDistanceComparison.py +0 -0
  248. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/EuclideanDistanceHeatmap.py +0 -0
  249. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/PCAComponentsPairwisePlots.py +0 -0
  250. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/StabilityAnalysisKeyword.py +0 -0
  251. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/StabilityAnalysisRandomNoise.py +0 -0
  252. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/StabilityAnalysisSynonyms.py +0 -0
  253. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/StabilityAnalysisTranslation.py +0 -0
  254. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/TSNEComponentsPairwisePlots.py +0 -0
  255. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/embeddings/utils.py +0 -0
  256. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ragas/NoiseSensitivity.py +0 -0
  257. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ragas/ResponseRelevancy.py +0 -0
  258. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/ragas/utils.py +0 -0
  259. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/AdjustedMutualInformation.py +0 -0
  260. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/AdjustedRandIndex.py +0 -0
  261. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/CalibrationCurve.py +0 -0
  262. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/ClassifierPerformance.py +0 -0
  263. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/ClassifierThresholdOptimization.py +0 -0
  264. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/ClusterCosineSimilarity.py +0 -0
  265. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/ClusterPerformanceMetrics.py +0 -0
  266. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/CompletenessScore.py +0 -0
  267. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/ConfusionMatrix.py +0 -0
  268. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/FowlkesMallowsScore.py +0 -0
  269. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/HomogeneityScore.py +0 -0
  270. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/KMeansClustersOptimization.py +0 -0
  271. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/MinimumAccuracy.py +0 -0
  272. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/MinimumROCAUCScore.py +0 -0
  273. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/ModelParameters.py +0 -0
  274. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/ModelsPerformanceComparison.py +0 -0
  275. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/OverfitDiagnosis.py +0 -0
  276. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/PermutationFeatureImportance.py +0 -0
  277. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/PopulationStabilityIndex.py +0 -0
  278. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/RegressionErrors.py +0 -0
  279. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/RegressionErrorsComparison.py +0 -0
  280. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/RegressionPerformance.py +0 -0
  281. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/RegressionR2Square.py +0 -0
  282. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/RegressionR2SquareComparison.py +0 -0
  283. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/SHAPGlobalImportance.py +0 -0
  284. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/ScoreProbabilityAlignment.py +0 -0
  285. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/SilhouettePlot.py +0 -0
  286. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/TrainingTestDegradation.py +0 -0
  287. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/VMeasure.py +0 -0
  288. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/WeakspotsDiagnosis.py +0 -0
  289. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/sklearn/__init__.py +0 -0
  290. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/AutoARIMA.py +0 -0
  291. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/DurbinWatsonTest.py +0 -0
  292. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/GINITable.py +0 -0
  293. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/KolmogorovSmirnov.py +0 -0
  294. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/Lilliefors.py +0 -0
  295. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/RegressionCoeffs.py +0 -0
  296. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/RegressionFeatureSignificance.py +0 -0
  297. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/RegressionModelForecastPlot.py +0 -0
  298. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/RegressionModelForecastPlotLevels.py +0 -0
  299. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/RegressionModelSensitivityPlot.py +0 -0
  300. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/RegressionModelSummary.py +0 -0
  301. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/RegressionPermutationFeatureImportance.py +0 -0
  302. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/__init__.py +0 -0
  303. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/model_validation/statsmodels/statsutils.py +0 -0
  304. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/CalibrationCurveDrift.py +0 -0
  305. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/ClassDiscriminationDrift.py +0 -0
  306. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/ClassImbalanceDrift.py +0 -0
  307. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/ClassificationAccuracyDrift.py +0 -0
  308. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/ConfusionMatrixDrift.py +0 -0
  309. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/CumulativePredictionProbabilitiesDrift.py +0 -0
  310. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/FeatureDrift.py +0 -0
  311. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/PredictionAcrossEachFeature.py +0 -0
  312. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/PredictionCorrelation.py +0 -0
  313. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/PredictionProbabilitiesHistogramDrift.py +0 -0
  314. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/PredictionQuantilesAcrossFeatures.py +0 -0
  315. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/ROCCurveDrift.py +0 -0
  316. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/ScoreBandsDrift.py +0 -0
  317. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/ScorecardHistogramDrift.py +0 -0
  318. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/ongoing_monitoring/TargetPredictionDistributionPlot.py +0 -0
  319. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/output.py +0 -0
  320. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/plots/BoxPlot.py +0 -0
  321. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/plots/CorrelationHeatmap.py +0 -0
  322. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/plots/HistogramPlot.py +0 -0
  323. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/plots/ViolinPlot.py +0 -0
  324. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/plots/__init__.py +0 -0
  325. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/prompt_validation/Bias.py +0 -0
  326. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/prompt_validation/Clarity.py +0 -0
  327. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/prompt_validation/Conciseness.py +0 -0
  328. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/prompt_validation/Delimitation.py +0 -0
  329. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/prompt_validation/NegativeInstruction.py +0 -0
  330. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/prompt_validation/Robustness.py +0 -0
  331. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/prompt_validation/Specificity.py +0 -0
  332. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/prompt_validation/__init__.py +0 -0
  333. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/run.py +0 -0
  334. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/stats/CorrelationAnalysis.py +0 -0
  335. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/stats/DescriptiveStats.py +0 -0
  336. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/stats/NormalityTests.py +0 -0
  337. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/stats/OutlierDetection.py +0 -0
  338. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/stats/__init__.py +0 -0
  339. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/test_providers.py +0 -0
  340. {validmind-2.13.4 → validmind-2.13.6}/validmind/tests/utils.py +0 -0
  341. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/__init__.py +0 -0
  342. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/classification/Accuracy.py +0 -0
  343. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/classification/F1.py +0 -0
  344. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/classification/Precision.py +0 -0
  345. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/classification/ROC_AUC.py +0 -0
  346. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/classification/Recall.py +0 -0
  347. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/regression/AdjustedRSquaredScore.py +0 -0
  348. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/regression/GiniCoefficient.py +0 -0
  349. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/regression/HuberLoss.py +0 -0
  350. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/regression/KolmogorovSmirnovStatistic.py +0 -0
  351. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/regression/MeanAbsoluteError.py +0 -0
  352. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/regression/MeanAbsolutePercentageError.py +0 -0
  353. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/regression/MeanBiasDeviation.py +0 -0
  354. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/regression/MeanSquaredError.py +0 -0
  355. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/regression/QuantileLoss.py +0 -0
  356. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/regression/RSquaredScore.py +0 -0
  357. {validmind-2.13.4 → validmind-2.13.6}/validmind/unit_metrics/regression/RootMeanSquaredError.py +0 -0
  358. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/__init__.py +0 -0
  359. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/dataset/__init__.py +0 -0
  360. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/dataset/utils.py +0 -0
  361. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/figure.py +0 -0
  362. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/html_progress.py +0 -0
  363. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/html_renderer.py +0 -0
  364. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/input.py +0 -0
  365. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/model.py +0 -0
  366. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/result/__init__.py +0 -0
  367. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/result/pii_filter.py +0 -0
  368. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/result/result.jinja +0 -0
  369. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/result/result.py +0 -0
  370. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/result/utils.py +0 -0
  371. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/test_suite/__init__.py +0 -0
  372. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/test_suite/runner.py +0 -0
  373. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/test_suite/summary.py +0 -0
  374. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/test_suite/test.py +0 -0
  375. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/test_suite/test_suite.py +0 -0
  376. {validmind-2.13.4 → validmind-2.13.6}/validmind/vm_models/text_generation_summary.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: validmind
3
- Version: 2.13.4
3
+ Version: 2.13.6
4
4
  Summary: ValidMind Library
5
5
  Author-email: Andres Rodriguez <andres@validmind.ai>, Juan Martinez <juan@validmind.ai>, Anil Sorathiya <anil@validmind.ai>, Luis Pallares <luis@validmind.ai>, John Walz <john@validmind.ai>
6
6
  License: DUAL LICENSE NOTICE
@@ -707,8 +707,10 @@ Requires-Dist: pandas<3.0.0,>=2.0.3
707
707
  Requires-Dist: plotly>=6.0.0
708
708
  Requires-Dist: polars
709
709
  Requires-Dist: python-dotenv
710
+ Requires-Dist: requests<3.0.0,>=2.28.0
710
711
  Requires-Dist: scikit-learn
711
712
  Requires-Dist: seaborn
713
+ Requires-Dist: segno<2.0.0,>=1.6.6
712
714
  Requires-Dist: tabulate<0.10.0,>=0.9.0
713
715
  Requires-Dist: tiktoken
714
716
  Requires-Dist: tqdm
@@ -724,7 +726,9 @@ Requires-Dist: langchain-google-genai; extra == 'all'
724
726
  Requires-Dist: langchain-openai>=0.1.8; extra == 'all'
725
727
  Requires-Dist: langchain<0.4.0,>=0.2.0; extra == 'all'
726
728
  Requires-Dist: langdetect; extra == 'all'
729
+ Requires-Dist: llvmlite<0.48,>=0.47.0; (python_version >= '3.14') and extra == 'all'
727
730
  Requires-Dist: nltk<4.0.0,>=3.8.1; extra == 'all'
731
+ Requires-Dist: numba>=0.65.1; (python_version >= '3.14') and extra == 'all'
728
732
  Requires-Dist: pyarrow<16; (python_version < '3.13') and extra == 'all'
729
733
  Requires-Dist: pyarrow<21,>=20; (python_version == '3.13') and extra == 'all'
730
734
  Requires-Dist: pyarrow<23,>=22; (python_version >= '3.14') and extra == 'all'
@@ -751,6 +755,8 @@ Requires-Dist: pyarrow<16; (python_version < '3.13') and extra == 'datasets'
751
755
  Requires-Dist: pyarrow<21,>=20; (python_version == '3.13') and extra == 'datasets'
752
756
  Requires-Dist: pyarrow<23,>=22; (python_version >= '3.14') and extra == 'datasets'
753
757
  Provides-Extra: explainability
758
+ Requires-Dist: llvmlite<0.48,>=0.47.0; (python_version >= '3.14') and extra == 'explainability'
759
+ Requires-Dist: numba>=0.65.1; (python_version >= '3.14') and extra == 'explainability'
754
760
  Requires-Dist: shap>=0.46.0; extra == 'explainability'
755
761
  Provides-Extra: huggingface
756
762
  Requires-Dist: sentencepiece<0.3.0,>=0.2.0; extra == 'huggingface'
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "validmind"
3
- version = "2.13.4"
3
+ version = "2.13.6"
4
4
  description = "ValidMind Library"
5
5
  readme = "README.pypi.md"
6
6
  requires-python = ">=3.9,<3.15"
@@ -14,6 +14,7 @@ authors = [
14
14
  ]
15
15
  dependencies = [
16
16
  "aiohttp[speedups] (<3.13.1)",
17
+ "requests (>=2.28.0,<3.0.0)",
17
18
  "ipywidgets",
18
19
  "kaleido (>=1.2.0,<2.0.0)",
19
20
  "matplotlib",
@@ -33,6 +34,7 @@ dependencies = [
33
34
  "tqdm",
34
35
  "anywidget",
35
36
  "beautifulsoup4",
37
+ "segno (>=1.6.6,<2.0.0)",
36
38
  ]
37
39
 
38
40
  [project.optional-dependencies]
@@ -63,6 +65,8 @@ all = [
63
65
  "pyarrow (>=22,<23) ; python_version >= '3.14'",
64
66
  "arch (>=7.0.0)",
65
67
  "shap (>=0.46.0)",
68
+ "numba (>=0.65.1) ; python_version >= '3.14'",
69
+ "llvmlite (>=0.47.0,<0.48) ; python_version >= '3.14'",
66
70
  "scorecardpy==0.1.9.6",
67
71
  "setuptools (<82)",
68
72
  ]
@@ -105,7 +109,11 @@ nlp = [
105
109
  pytorch = ["torch (>=2.0.0)"]
106
110
  stats = ["scipy", "statsmodels (>=0.14.2,<0.15.0)", "arch (>=7.0.0)"]
107
111
  xgboost = ["xgboost (>=1.5.2,<3)"]
108
- explainability = ["shap (>=0.46.0)"]
112
+ explainability = [
113
+ "shap (>=0.46.0)",
114
+ "numba (>=0.65.1) ; python_version >= '3.14'",
115
+ "llvmlite (>=0.47.0,<0.48) ; python_version >= '3.14'",
116
+ ]
109
117
  credit_risk = ["scorecardpy==0.1.9.6", "setuptools (<82)"]
110
118
  datasets = [
111
119
  "datasets (>=2.10.0,<3.0.0) ; python_version < '3.14'",
@@ -122,7 +130,7 @@ pii-detection = [
122
130
 
123
131
  [dependency-groups]
124
132
  dev = [
125
- "black>=22.1.0,<23",
133
+ "black>=22.1.0,<26",
126
134
  "click",
127
135
  "cython>=0.29.34,<0.30",
128
136
  "docstring-parser",
@@ -0,0 +1 @@
1
+ __version__ = "2.13.6"
@@ -17,10 +17,11 @@ __client = None
17
17
  __model = None
18
18
  __judge_llm = None
19
19
  __judge_embeddings = None
20
+ __judge_llm_explicitly_set = False
20
21
  OPENAI_MODEL = "gpt-4.1"
21
22
  OPENAI_EMBEDDINGS_MODEL = "text-embedding-3-small"
22
23
  GEMINI_MODEL = "gemini-2.5-pro"
23
- GEMINI_EMBEDDINGS_MODEL = "models/text-embedding-004"
24
+ GEMINI_EMBEDDINGS_MODEL = "gemini-embedding-001"
24
25
 
25
26
  # can be None, True or False (ternary to represent initial state, ack and failed ack)
26
27
  __ack = None
@@ -59,10 +60,7 @@ def _get_configured_provider():
59
60
  if os.getenv("AZURE_OPENAI_KEY"):
60
61
  return "azure"
61
62
 
62
- if _get_google_api_key():
63
- return "gemini"
64
-
65
- return None
63
+ return "gemini"
66
64
 
67
65
 
68
66
  def get_client_and_model():
@@ -104,18 +102,12 @@ def get_client_and_model():
104
102
 
105
103
  logger.debug(f"Using Azure OpenAI {__model} for generating descriptions")
106
104
 
107
- elif provider == "gemini":
105
+ else:
108
106
  __client = None
109
107
  __model = os.getenv("GEMINI_MODEL", GEMINI_MODEL)
110
108
 
111
109
  logger.debug(f"Using Gemini {__model} for generating descriptions")
112
110
 
113
- else:
114
- raise ValueError(
115
- "OPENAI_API_KEY, AZURE_OPENAI_KEY, GOOGLE_API_KEY, or GEMINI_API_KEY "
116
- "must be setup to use LLM features"
117
- )
118
-
119
111
  return __client, __model
120
112
 
121
113
 
@@ -202,16 +194,18 @@ def _build_gemini_judge_config(model):
202
194
  langchain_google_genai, "GoogleGenerativeAIEmbeddings"
203
195
  )
204
196
  google_api_key = _get_google_api_key()
197
+ chat_kwargs = {"model": model}
198
+ embeddings_kwargs = {
199
+ "model": os.getenv("GEMINI_EMBEDDINGS_MODEL", GEMINI_EMBEDDINGS_MODEL),
200
+ }
201
+
202
+ if google_api_key:
203
+ chat_kwargs["api_key"] = google_api_key
204
+ embeddings_kwargs["google_api_key"] = google_api_key
205
205
 
206
206
  return (
207
- ChatGoogleGenerativeAI(
208
- model=model,
209
- api_key=google_api_key,
210
- ),
211
- GoogleGenerativeAIEmbeddings(
212
- model=os.getenv("GEMINI_EMBEDDINGS_MODEL", GEMINI_EMBEDDINGS_MODEL),
213
- google_api_key=google_api_key,
214
- ),
207
+ ChatGoogleGenerativeAI(**chat_kwargs),
208
+ GoogleGenerativeAIEmbeddings(**embeddings_kwargs),
215
209
  )
216
210
 
217
211
 
@@ -230,6 +224,162 @@ def _build_openai_judge_config(client, model):
230
224
  )
231
225
 
232
226
 
227
+ def _import_deepeval_base_llm():
228
+ try:
229
+ deepeval_base_model = importlib.import_module("deepeval.models.base_model")
230
+ except ImportError:
231
+ raise ImportError(
232
+ "Please run `pip install validmind[llm]` to use Gemini DeepEval scorers"
233
+ )
234
+
235
+ return getattr(deepeval_base_model, "DeepEvalBaseLLM")
236
+
237
+
238
+ def _unwrap_deepeval_response(response):
239
+ return getattr(response, "content", response)
240
+
241
+
242
+ def _is_reason_only_schema(schema):
243
+ """True when ``schema`` is a single-field ``{reason}`` explanation schema.
244
+
245
+ DeepEval's ``*ScoreReason`` schemas carry only the human-readable explanation
246
+ and do not affect the metric score, so a missing value can be degraded safely.
247
+ """
248
+ fields = getattr(schema, "model_fields", None) or getattr(
249
+ schema, "__fields__", None
250
+ )
251
+ try:
252
+ return set(fields.keys()) == {"reason"}
253
+ except Exception:
254
+ return False
255
+
256
+
257
+ def _require_structured_response(result, schema):
258
+ """Guard against a judge LLM returning no parseable structured output.
259
+
260
+ Gemini's default function-calling path yields ``None`` when the model
261
+ response contains no tool call. Returning that ``None`` to DeepEval surfaces
262
+ as a cryptic ``'NoneType' object has no attribute 'reason'``.
263
+
264
+ For reason-only schemas the metric score is already computed from earlier
265
+ verdict calls, so a missing explanation is cosmetic: degrade to a placeholder
266
+ reason and keep the score. Score-bearing schemas (statements, verdicts) are
267
+ never faked -- doing so would yield a silently wrong score -- so those raise.
268
+ """
269
+ if result is not None:
270
+ return result
271
+
272
+ schema_name = getattr(schema, "__name__", schema)
273
+
274
+ if _is_reason_only_schema(schema):
275
+ logger.warning(
276
+ "Judge LLM returned no structured output for %s; recording the score "
277
+ "with an empty explanation.",
278
+ schema_name,
279
+ )
280
+ return schema(reason="N/A (judge LLM returned no explanation)")
281
+
282
+ raise ValueError(
283
+ f"Judge LLM returned no parseable structured output for {schema_name}. "
284
+ "This usually means the model produced no tool call for the requested "
285
+ "schema. Try a different judge model, or check provider quotas and "
286
+ "safety settings."
287
+ )
288
+
289
+
290
+ def _structured_generate(chat_model, prompt, schema):
291
+ """Invoke ``chat_model`` for structured output, retrying via json_mode.
292
+
293
+ Gemini's default function-calling path can return ``None`` when the model
294
+ emits no tool call; json_mode binds a response schema and is deterministic.
295
+ """
296
+ result = chat_model.with_structured_output(schema).invoke(prompt)
297
+ if result is None:
298
+ try:
299
+ result = chat_model.with_structured_output(
300
+ schema, method="json_mode"
301
+ ).invoke(prompt)
302
+ except Exception:
303
+ pass
304
+ return _require_structured_response(result, schema)
305
+
306
+
307
+ async def _a_structured_generate(chat_model, prompt, schema):
308
+ """Async counterpart of :func:`_structured_generate`."""
309
+ result = await chat_model.with_structured_output(schema).ainvoke(prompt)
310
+ if result is None:
311
+ try:
312
+ result = await chat_model.with_structured_output(
313
+ schema, method="json_mode"
314
+ ).ainvoke(prompt)
315
+ except Exception:
316
+ pass
317
+ return _require_structured_response(result, schema)
318
+
319
+
320
+ def _build_langchain_deepeval_model(chat_model):
321
+ """Wrap any LangChain BaseChatModel as a DeepEval-compatible model.
322
+
323
+ Used when set_judge_config() has been called so that DeepEval scorers
324
+ honour the same judge model as prompt-validation and RAGAS tests.
325
+ """
326
+ DeepEvalBaseLLM = _import_deepeval_base_llm()
327
+
328
+ class LangChainDeepEvalModel(DeepEvalBaseLLM):
329
+ def __init__(self, model):
330
+ self._chat_model = model
331
+ self.model = self.load_model()
332
+
333
+ def load_model(self, *args, **kwargs):
334
+ return self._chat_model
335
+
336
+ def generate(self, prompt: str, schema=None):
337
+ chat_model = self.load_model()
338
+ if schema is not None and hasattr(chat_model, "with_structured_output"):
339
+ return _structured_generate(chat_model, prompt, schema)
340
+ return _unwrap_deepeval_response(chat_model.invoke(prompt))
341
+
342
+ async def a_generate(self, prompt: str, schema=None):
343
+ chat_model = self.load_model()
344
+ if schema is not None and hasattr(chat_model, "with_structured_output"):
345
+ return await _a_structured_generate(chat_model, prompt, schema)
346
+ return _unwrap_deepeval_response(await chat_model.ainvoke(prompt))
347
+
348
+ def get_model_name(self, *args, **kwargs):
349
+ for attr in ("model", "model_name", "azure_deployment"):
350
+ val = getattr(self._chat_model, attr, None)
351
+ if val:
352
+ return val
353
+ return type(self._chat_model).__name__
354
+
355
+ return LangChainDeepEvalModel(chat_model)
356
+
357
+
358
+ def _build_gemini_deepeval_model(model):
359
+ judge_llm, _ = _build_gemini_judge_config(model)
360
+ return _build_langchain_deepeval_model(judge_llm)
361
+
362
+
363
+ def run_deepeval_evaluation(*, test_cases, metrics):
364
+ try:
365
+ from deepeval import evaluate
366
+
367
+ deepeval_test_run = importlib.import_module("deepeval.test_run.test_run")
368
+ except ImportError:
369
+ raise ImportError(
370
+ "Please run `pip install validmind[llm]` to use Gemini DeepEval scorers"
371
+ )
372
+
373
+ original_is_confident = deepeval_test_run.is_confident
374
+
375
+ try:
376
+ # ValidMind scorers should run locally without depending on Confident AI login state.
377
+ deepeval_test_run.is_confident = lambda: False
378
+ return evaluate(test_cases=test_cases, metrics=metrics)
379
+ finally:
380
+ deepeval_test_run.is_confident = original_is_confident
381
+
382
+
233
383
  def get_judge_config(judge_llm=None, judge_embeddings=None):
234
384
  Embeddings, BaseChatModel, FunctionModel = _import_judge_dependencies()
235
385
 
@@ -265,11 +415,21 @@ def get_deepeval_model():
265
415
  OpenAI/Azure scorers currently pass a model string. Gemini support requires a
266
416
  native DeepEval model object so the provider can be configured correctly.
267
417
  """
418
+ if (
419
+ __judge_llm_explicitly_set
420
+ and __judge_llm is not None
421
+ and __judge_embeddings is not None
422
+ ):
423
+ return _build_langchain_deepeval_model(__judge_llm)
268
424
 
269
425
  provider = _get_configured_provider()
270
426
  _, model = get_client_and_model()
271
427
 
272
428
  if provider == "gemini":
429
+ google_api_key = _get_google_api_key()
430
+ if google_api_key is None:
431
+ return _build_gemini_deepeval_model(model)
432
+
273
433
  try:
274
434
  deepeval_models = importlib.import_module("deepeval.models")
275
435
  except ImportError:
@@ -280,7 +440,7 @@ def get_deepeval_model():
280
440
  GeminiModel = getattr(deepeval_models, "GeminiModel")
281
441
  return GeminiModel(
282
442
  model=model,
283
- api_key=_get_google_api_key(),
443
+ api_key=google_api_key,
284
444
  temperature=0,
285
445
  )
286
446
 
@@ -288,7 +448,7 @@ def get_deepeval_model():
288
448
 
289
449
 
290
450
  def set_judge_config(judge_llm, judge_embeddings):
291
- global __judge_llm, __judge_embeddings
451
+ global __judge_llm, __judge_embeddings, __judge_llm_explicitly_set
292
452
  try:
293
453
  from langchain_core.embeddings import Embeddings
294
454
  from langchain_core.language_models.chat_models import BaseChatModel
@@ -301,12 +461,13 @@ def set_judge_config(judge_llm, judge_embeddings):
301
461
  ):
302
462
  __judge_llm = judge_llm
303
463
  __judge_embeddings = judge_embeddings
304
- # Assuming 'your_object' is the object you want to check
464
+ __judge_llm_explicitly_set = True
305
465
  elif isinstance(judge_llm, FunctionModel) and isinstance(
306
466
  judge_embeddings, FunctionModel
307
467
  ):
308
468
  __judge_llm = judge_llm.model
309
469
  __judge_embeddings = judge_embeddings.model
470
+ __judge_llm_explicitly_set = True
310
471
  else:
311
472
  raise ValueError(
312
473
  "Provided Judge LLM/Embeddings are not Langchain compatible. Ensure the judge LLM/embedding provided are an instance of "
@@ -21,7 +21,12 @@ from aiohttp import FormData
21
21
 
22
22
  from .__version__ import __version__
23
23
  from .client_config import client_config
24
- from .errors import MissingAPICredentialsError, MissingModelIdError, raise_api_error
24
+ from .errors import (
25
+ MissingAPICredentialsError,
26
+ MissingModelIdError,
27
+ ValidMindAuthError,
28
+ raise_api_error,
29
+ )
25
30
  from .logging import get_logger, log_api_operation
26
31
  from .utils import NumpyEncoder, is_html, md_to_html, run_async
27
32
  from .vm_models.figure import Figure
@@ -34,10 +39,30 @@ _api_host = os.getenv("VM_API_HOST")
34
39
  _model_cuid = os.getenv("VM_API_MODEL")
35
40
  _document = None
36
41
  _monitoring = False
42
+ _auth_mode = "api_key"
43
+ _access_token: Optional[str] = None
44
+ _oidc_login_context: Optional[Dict[str, str]] = None
37
45
 
38
46
  __api_session: Optional[aiohttp.ClientSession] = None
39
47
 
40
48
 
49
+ def _invalidate_async_session() -> None:
50
+ """Drop the aiohttp session so the next request picks up new headers."""
51
+ global __api_session
52
+ sess = __api_session
53
+ __api_session = None
54
+ if sess is None or sess.closed:
55
+ return
56
+ try:
57
+ loop = asyncio.get_running_loop()
58
+ loop.create_task(sess.close())
59
+ except RuntimeError:
60
+ try:
61
+ asyncio.run(sess.close())
62
+ except RuntimeError:
63
+ pass
64
+
65
+
41
66
  @atexit.register
42
67
  def _close_session():
43
68
  """Closes the async client session at exit."""
@@ -70,14 +95,21 @@ def get_api_model() -> Optional[str]:
70
95
 
71
96
  def _get_api_headers() -> Dict[str, str]:
72
97
  headers = {
73
- "X-API-KEY": _api_key,
74
- "X-API-SECRET": _api_secret,
75
98
  "X-MODEL-CUID": _model_cuid,
76
99
  "X-MONITORING": str(_monitoring),
77
100
  "X-LIBRARY-VERSION": __version__,
78
101
  }
79
102
  if _document:
80
103
  headers["X-DOCUMENT-TYPE"] = _document
104
+ if _auth_mode == "oidc":
105
+ if not _access_token:
106
+ raise ValidMindAuthError(
107
+ "OAuth access token is missing. Run vm.init() again with issuer and client_id."
108
+ )
109
+ headers["Authorization"] = f"Bearer {_access_token}"
110
+ else:
111
+ headers["X-API-KEY"] = _api_key
112
+ headers["X-API-SECRET"] = _api_secret
81
113
  return headers
82
114
 
83
115
 
@@ -192,14 +224,71 @@ def _ping() -> Dict[str, Any]:
192
224
  )
193
225
 
194
226
 
227
+ def _obtain_oidc_tokens(
228
+ issuer: str,
229
+ client_id: str,
230
+ scope: str,
231
+ audience: Optional[str] = None,
232
+ ) -> Dict[str, Any]:
233
+ """Return a credentials entry dict with access_token, expires_at, refresh_token, etc."""
234
+ from .credentials_store import (
235
+ delete_cached_entry,
236
+ get_cached_entry,
237
+ is_expired,
238
+ normalize_client_id,
239
+ normalize_issuer,
240
+ upsert_cached_entry,
241
+ )
242
+ from .oidc_device import run_device_flow, try_refresh_cached_tokens
243
+
244
+ norm_issuer = normalize_issuer(issuer)
245
+ norm_client_id = normalize_client_id(client_id)
246
+ cached = get_cached_entry(norm_issuer, norm_client_id, audience=audience)
247
+ if cached and not is_expired(cached):
248
+ return cached
249
+ if cached and cached.get("refresh_token"):
250
+ try:
251
+ new_tokens = try_refresh_cached_tokens(
252
+ norm_issuer,
253
+ norm_client_id,
254
+ cached["refresh_token"],
255
+ scope,
256
+ audience=audience,
257
+ )
258
+ upsert_cached_entry(
259
+ norm_issuer, norm_client_id, new_tokens, audience=audience
260
+ )
261
+ return new_tokens
262
+ except ValidMindAuthError:
263
+ delete_cached_entry(norm_issuer, norm_client_id, audience=audience)
264
+ tokens = run_device_flow(norm_issuer, norm_client_id, scope, audience=audience)
265
+ upsert_cached_entry(norm_issuer, norm_client_id, tokens, audience=audience)
266
+ return tokens
267
+
268
+
269
+ def _is_entra_issuer(issuer: str) -> bool:
270
+ return "login.microsoftonline.com" in issuer.lower()
271
+
272
+
273
+ def _select_oidc_bearer_token(entry: Dict[str, Any]) -> str:
274
+ if _is_entra_issuer(entry.get("issuer", "")) and entry.get("id_token"):
275
+ return entry["id_token"]
276
+ return entry["access_token"]
277
+
278
+
195
279
  def init(
196
280
  api_key: Optional[str] = None,
197
281
  api_secret: Optional[str] = None,
198
282
  api_host: Optional[str] = None,
283
+ api_url: Optional[str] = None,
199
284
  model: Optional[str] = None,
200
285
  monitoring: bool = False,
201
286
  generate_descriptions: Optional[bool] = None,
202
287
  document: Optional[str] = None,
288
+ issuer: Optional[str] = None,
289
+ client_id: Optional[str] = None,
290
+ scope: Optional[str] = None,
291
+ audience: Optional[str] = None,
203
292
  ):
204
293
  """
205
294
  Initializes the API client instances and calls the /ping endpoint to ensure
@@ -208,36 +297,82 @@ def init(
208
297
  If the API key and secret are not provided, the client will attempt to
209
298
  retrieve them from the environment variables `VM_API_KEY` and `VM_API_SECRET`.
210
299
 
300
+ Alternatively, pass ``issuer`` and ``client_id`` or set their ``VM_OIDC_*``
301
+ environment variables to authenticate via the OIDC device authorization flow
302
+ (RFC 8628). Tokens are cached under ``~/.validmind/credentials.json``. Do not
303
+ combine API keys with OIDC parameters.
304
+
211
305
  Args:
212
306
  model (str, optional): The model CUID. Defaults to None.
213
307
  api_key (str, optional): The API key. Defaults to None.
214
308
  api_secret (str, optional): The API secret. Defaults to None.
215
- api_host (str, optional): The API host. Defaults to None.
309
+ api_host (str, optional): The API host (tracking base URL). Defaults to
310
+ env ``VM_API_HOST`` or ``VM_API_URL``.
311
+ api_url (str, optional): Alias for ``api_host``. Defaults to env
312
+ ``VM_API_URL`` or ``VM_API_HOST``.
216
313
  monitoring (bool): The ongoing monitoring flag. Defaults to False.
217
314
  generate_descriptions (bool, optional): Whether to use GenAI to generate test result descriptions. Defaults to True.
218
315
  document (str, optional): The name of the document. Omitting this argument is deprecated.
316
+ issuer (str, optional): OIDC issuer URL (e.g. Entra tenant ``.../v2.0``).
317
+ Can be set via env ``VM_OIDC_ISSUER``.
318
+ client_id (str, optional): OAuth public client id for device flow. Can be
319
+ set via env ``VM_OIDC_CLIENT_ID``.
320
+ scope (str, optional): OAuth scopes (default ``openid profile email``).
321
+ Can be set via env ``VM_OIDC_SCOPE``.
322
+ audience (str, optional): Resource / API identifier for the access token
323
+ (e.g. Auth0 API Identifier). Use the same value the ValidMind backend
324
+ expects as ``api_audience`` so the provider can issue RS256 API tokens.
325
+ Can be set via env ``VM_OIDC_AUDIENCE``.
326
+
219
327
  Raises:
220
- ValueError: If the API key and secret are not provided
328
+ MissingAPICredentialsError: If neither API keys nor OIDC parameters can be resolved.
329
+ MissingModelIdError: If model id is missing.
330
+ ValidMindAuthError: If OIDC configuration conflicts or login fails.
221
331
  """
222
332
  global _api_key, _api_secret, _api_host, _model_cuid, _monitoring, _document
333
+ global _auth_mode, _access_token, _oidc_login_context
223
334
 
224
335
  if api_key == "...":
225
336
  # special case to detect when running a notebook placeholder (...)
226
337
  # will override with environment variables for easier local development
227
- api_host = api_key = api_secret = model = None
338
+ api_host = api_url = api_key = api_secret = model = issuer = client_id = (
339
+ audience
340
+ ) = None
228
341
 
229
342
  _model_cuid = model or os.getenv("VM_API_MODEL")
230
343
  if _model_cuid is None:
231
344
  raise MissingModelIdError()
232
345
 
233
- _api_key = api_key or os.getenv("VM_API_KEY")
234
- _api_secret = api_secret or os.getenv("VM_API_SECRET")
235
- if _api_key is None or _api_secret is None:
236
- raise MissingAPICredentialsError()
237
-
238
- _api_host = api_host or os.getenv(
239
- "VM_API_HOST", "http://localhost:5000/api/v1/tracking/"
346
+ resolved_host = (
347
+ api_url
348
+ or api_host
349
+ or os.getenv("VM_API_URL")
350
+ or os.getenv("VM_API_HOST", "http://localhost:5000/api/v1/tracking/")
351
+ )
352
+ oidc_issuer = issuer if issuer is not None else os.getenv("VM_OIDC_ISSUER")
353
+ oidc_client_id = (
354
+ client_id if client_id is not None else os.getenv("VM_OIDC_CLIENT_ID")
355
+ )
356
+ oidc_scope = scope if scope is not None else os.getenv("VM_OIDC_SCOPE")
357
+
358
+ env_key = api_key if api_key is not None else os.getenv("VM_API_KEY")
359
+ env_secret = api_secret if api_secret is not None else os.getenv("VM_API_SECRET")
360
+ has_api_creds = (
361
+ env_key is not None
362
+ and env_secret is not None
363
+ and env_key != ""
364
+ and env_secret != ""
240
365
  )
366
+ has_oidc = bool(oidc_issuer and oidc_client_id)
367
+ if has_oidc and has_api_creds:
368
+ raise ValidMindAuthError(
369
+ "Provide either API credentials (api_key and api_secret) or OIDC "
370
+ "(issuer and client_id), not both."
371
+ )
372
+ if oidc_issuer and not oidc_client_id:
373
+ raise ValidMindAuthError("client_id is required when issuer is set.")
374
+ if oidc_client_id and not oidc_issuer:
375
+ raise ValidMindAuthError("issuer is required when client_id is set.")
241
376
 
242
377
  _monitoring = monitoring
243
378
 
@@ -251,6 +386,41 @@ def init(
251
386
  )
252
387
 
253
388
  _document = document
389
+
390
+ if has_oidc:
391
+ _auth_mode = "oidc"
392
+ _api_key = None
393
+ _api_secret = None
394
+ _api_host = resolved_host
395
+ scope_val = oidc_scope or "openid profile email"
396
+ from .credentials_store import normalize_audience
397
+
398
+ oidc_audience_val = normalize_audience(
399
+ audience if audience is not None else os.getenv("VM_OIDC_AUDIENCE")
400
+ )
401
+ oidc_audience_opt = oidc_audience_val or None
402
+ entry = _obtain_oidc_tokens(
403
+ oidc_issuer, oidc_client_id, scope_val, audience=oidc_audience_opt
404
+ )
405
+ _access_token = _select_oidc_bearer_token(entry)
406
+ _oidc_login_context = {
407
+ "issuer": entry["issuer"],
408
+ "client_id": entry["client_id"],
409
+ "scope": scope_val,
410
+ "audience": entry.get("audience") or oidc_audience_val,
411
+ }
412
+ _invalidate_async_session()
413
+ else:
414
+ if env_key is None or env_secret is None:
415
+ raise MissingAPICredentialsError()
416
+ _auth_mode = "api_key"
417
+ _access_token = None
418
+ _oidc_login_context = None
419
+ _api_key = env_key
420
+ _api_secret = env_secret
421
+ _api_host = resolved_host
422
+ _invalidate_async_session()
423
+
254
424
  reload()
255
425
 
256
426