featrixsphere 0.2.6379__tar.gz → 0.2.6710__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 (333) hide show
  1. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/PKG-INFO +1 -1
  2. featrixsphere-0.2.6710/VERSION +1 -0
  3. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/__init__.py +1 -1
  4. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/api/client.py +28 -0
  5. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/api/foundational_model.py +394 -20
  6. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/api/http_client.py +37 -4
  7. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/api/prediction_result.py +98 -9
  8. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/api/predictor.py +77 -3
  9. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/client.py +27 -16
  10. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere.egg-info/PKG-INFO +1 -1
  11. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere.egg-info/SOURCES.txt +24 -1
  12. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/requirements.txt +2 -0
  13. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/api.py +217 -47
  14. featrixsphere-0.2.6710/src/demo_label_updates.py +214 -0
  15. featrixsphere-0.2.6710/src/example_api_usage.py +191 -0
  16. featrixsphere-0.2.6710/src/example_prediction_feedback.py +121 -0
  17. featrixsphere-0.2.6710/src/example_train_predictor.py +116 -0
  18. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/celery_job_recovery.py +160 -6
  19. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/convergence_monitor.py +27 -4
  20. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/es_training.py +25 -5
  21. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/adaptive_event_log.py +14 -0
  22. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/charting.py +45 -16
  23. featrixsphere-0.2.6710/src/lib/featrix/neural/checkpoint_validation.py +697 -0
  24. featrixsphere-0.2.6710/src/lib/featrix/neural/constants.py +30 -0
  25. featrixsphere-0.2.6710/src/lib/featrix/neural/data_fips.py +3391 -0
  26. featrixsphere-0.2.6710/src/lib/featrix/neural/data_free_email_domains.py +4884 -0
  27. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/detect.py +830 -3
  28. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/dropout_scheduler.py +54 -0
  29. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/dynamic_relationship_extractor.py +371 -73
  30. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/embedded_space.py +927 -162
  31. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/encoders.py +253 -41
  32. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/es_training_callbacks.py +2 -2
  33. featrixsphere-0.2.6710/src/lib/featrix/neural/fips_codec.py +522 -0
  34. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/foundation_input_data.py +71 -0
  35. featrixsphere-0.2.6710/src/lib/featrix/neural/geo_json_codec.py +530 -0
  36. featrixsphere-0.2.6710/src/lib/featrix/neural/geo_json_ops.py +710 -0
  37. featrixsphere-0.2.6710/src/lib/featrix/neural/geo_spread.py +436 -0
  38. featrixsphere-0.2.6710/src/lib/featrix/neural/geocode.py +587 -0
  39. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/gpu_utils.py +220 -2
  40. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/gradient_flow.py +1 -1
  41. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/guardrails.py +63 -24
  42. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/hybrid_column_detector.py +199 -37
  43. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/hybrid_encoders.py +256 -74
  44. featrixsphere-0.2.6710/src/lib/featrix/neural/hybrid_scalar_set_codec.py +600 -0
  45. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/input_data_set.py +2 -2
  46. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/io_utils.py +107 -184
  47. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/llm/schema_analyzer.py +102 -35
  48. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/loss_framework.py +373 -4
  49. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/model_config.py +6 -0
  50. featrixsphere-0.2.6710/src/lib/featrix/neural/phone_codec.py +925 -0
  51. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_all_codecs.py +127 -0
  52. featrixsphere-0.2.6710/src/lib/featrix/neural/qa/test_phone_zip_geo.py +424 -0
  53. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_predict_during_training.py +102 -118
  54. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/relationship_estimator.py +3 -10
  55. featrixsphere-0.2.6710/src/lib/featrix/neural/relationship_ops_base.py +325 -0
  56. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/scalar_codec.py +230 -189
  57. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/set_codec.py +91 -6
  58. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/simple_string_cache.py +4 -10
  59. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/single_predictor.py +1676 -350
  60. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/sphere_config.py +429 -11
  61. featrixsphere-0.2.6710/src/lib/featrix/neural/sphere_init.py +138 -0
  62. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/sqlite_utils.py +139 -0
  63. featrixsphere-0.2.6710/src/lib/featrix/neural/strategy_ops_base.py +284 -0
  64. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/strategy_scalar_scalar_ops.py +5 -8
  65. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/strategy_set_scalar_ops.py +6 -8
  66. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/strategy_string_scalar_ops.py +6 -8
  67. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/string_analysis.py +384 -0
  68. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/string_cache.py +0 -14
  69. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/string_codec.py +271 -180
  70. featrixsphere-0.2.6710/src/lib/featrix/neural/tensor_utils.py +181 -0
  71. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/training_data_timeline.py +16 -0
  72. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/training_history_db.py +49 -26
  73. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/transformer_encoder.py +137 -85
  74. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/type_aware_ops_config.py +39 -0
  75. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/xgboost_classifier.py +107 -6
  76. featrixsphere-0.2.6710/src/lib/featrix/neural/year_json_codec.py +563 -0
  77. featrixsphere-0.2.6710/src/lib/featrix/neural/year_json_ops.py +526 -0
  78. featrixsphere-0.2.6710/src/lib/featrix/neural/zip_codec.py +797 -0
  79. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/job_manager.py +10 -2
  80. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/model_card_repair.py +39 -3
  81. featrixsphere-0.2.6710/src/lib/runtime_version_manager.py +469 -0
  82. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/session_manager.py +6 -0
  83. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/single_predictor_training.py +51 -25
  84. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/vector_db.py +77 -0
  85. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/weightwatcher_tracking.py +66 -4
  86. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/load_and_test_model.py +12 -9
  87. featrixsphere-0.2.6710/src/prediction_server.py +682 -0
  88. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/system_monitor.py +159 -2
  89. featrixsphere-0.2.6710/tests/test_checkpoint_on_taco.py +107 -0
  90. featrixsphere-0.2.6710/tests/test_local_checkpoint.py +80 -0
  91. featrixsphere-0.2.6710/tests/test_runtime_version_manager.py +146 -0
  92. featrixsphere-0.2.6379/VERSION +0 -1
  93. featrixsphere-0.2.6379/src/demo_label_updates.py +0 -259
  94. featrixsphere-0.2.6379/src/example_api_usage.py +0 -195
  95. featrixsphere-0.2.6379/src/example_prediction_feedback.py +0 -109
  96. featrixsphere-0.2.6379/src/example_train_predictor.py +0 -106
  97. featrixsphere-0.2.6379/src/prediction_server.py +0 -337
  98. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/MANIFEST.in +0 -0
  99. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/README.md +0 -0
  100. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrix-update.py +0 -0
  101. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/api/__init__.py +0 -0
  102. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/api/api_endpoint.py +0 -0
  103. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/api/notebook_helper.py +0 -0
  104. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/api/reference_record.py +0 -0
  105. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere/api/vector_database.py +0 -0
  106. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere.egg-info/dependency_links.txt +0 -0
  107. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere.egg-info/entry_points.txt +0 -0
  108. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere.egg-info/not-zip-safe +0 -0
  109. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere.egg-info/requires.txt +0 -0
  110. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/featrixsphere.egg-info/top_level.txt +0 -0
  111. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/nv-install.sh +0 -0
  112. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/setup.cfg +0 -0
  113. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/setup.py +0 -0
  114. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/auto_upgrade_monitor.py +0 -0
  115. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/build_version.py +0 -0
  116. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/celery_app.py +0 -0
  117. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/cluster_movie_renderer.py +0 -0
  118. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/config.py +0 -0
  119. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/demo_existing_model.py +0 -0
  120. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/deploy.py +0 -0
  121. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/deploy_cache_debug.sh +0 -0
  122. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/ensure_watchdog_running.sh +0 -0
  123. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/error_tracker.py +0 -0
  124. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/event_log.py +0 -0
  125. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/featrix_watchdog.py +0 -0
  126. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/gc_cleanup.py +0 -0
  127. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/api_event_retry.py +0 -0
  128. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/backing_db.py +0 -0
  129. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/crash_tracker.py +0 -0
  130. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/distribution_shift_detector.py +0 -0
  131. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/embedding_space_io.py +0 -0
  132. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/epoch_projections.py +0 -0
  133. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/es_projections.py +0 -0
  134. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/es_training_wrapper.py +0 -0
  135. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/__init__.py +0 -0
  136. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/auto_calibrate.py +0 -0
  137. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/download-data/build_geo_weather_db.py +0 -0
  138. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/download-data/download_geographic_data.py +0 -0
  139. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/download-data/download_road_data.py +0 -0
  140. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/download-data/download_weather_data.py +0 -0
  141. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/download-data/install-data.sh +0 -0
  142. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/__init__.py +0 -0
  143. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/auc_animation.py +0 -0
  144. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/calibration_utils.py +0 -0
  145. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/causal_relationship_scorer.py +0 -0
  146. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/classification_metrics.py +0 -0
  147. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/cluster_cohesion_tracker.py +0 -0
  148. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/config.py +0 -0
  149. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/curve_plots_example.py +0 -0
  150. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/customer_quality_tracker.py +0 -0
  151. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/data_frame_data_set.py +0 -0
  152. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/dataloader_utils.py +0 -0
  153. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/default_training_rules.py +0 -0
  154. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/dimension_validator.py +0 -0
  155. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/domain_codec.py +0 -0
  156. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/duration_ops.py +0 -0
  157. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/email_codec.py +0 -0
  158. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/email_domain_ops.py +0 -0
  159. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/embedding_lr_scheduler.py +0 -0
  160. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/embedding_quality.py +0 -0
  161. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/embedding_space_utils.py +0 -0
  162. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/embedding_utils.py +0 -0
  163. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/enrich.py +0 -0
  164. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/es_projection.py +0 -0
  165. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/exceptions.py +0 -0
  166. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/featrix_csv.py +0 -0
  167. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/featrix_json.py +0 -0
  168. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/featrix_module_dict.py +0 -0
  169. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/featrix_token.py +0 -0
  170. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/feature_effectiveness_tracker.py +0 -0
  171. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/feature_engineer.py +0 -0
  172. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/feature_suggestion_tracker.py +0 -0
  173. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/geo_foundation.py +0 -0
  174. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/geo_ops.py +0 -0
  175. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/graph_encoder.py +0 -0
  176. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/graph_encoder_training.py +0 -0
  177. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/host_memory_tracker.py +0 -0
  178. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/hubspot_free_domains_list_may_2025.py +0 -0
  179. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/hyperparam_search.py +0 -0
  180. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/input_data_file.py +0 -0
  181. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/integrity.py +0 -0
  182. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/ip_address_ops.py +0 -0
  183. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/json_cache.py +0 -0
  184. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/json_codec.py +0 -0
  185. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/junction_adapter.py +0 -0
  186. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/llm/__init__.py +0 -0
  187. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/local_string_cache.py +0 -0
  188. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/logging_config.py +0 -0
  189. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/loss_functions/__init__.py +0 -0
  190. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/loss_functions/list_versions.py +0 -0
  191. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/loss_functions/loss_functions_01Jan2026.py +0 -0
  192. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/loss_functions/loss_functions_01Jul2025.py +0 -0
  193. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/loss_functions/loss_functions_21Jan2026.py +0 -0
  194. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/loss_short_embedding.py +0 -0
  195. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/lr_timeline.py +0 -0
  196. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/mask_bias_tracker.py +0 -0
  197. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/mask_tracker.py +0 -0
  198. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/model_hash.py +0 -0
  199. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/movie_frame_task.py +0 -0
  200. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/multi_table_dataset.py +0 -0
  201. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/multi_table_embedding_space.py +0 -0
  202. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/network_viz.py +0 -0
  203. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/pair_scorer.py +0 -0
  204. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/per_epoch_quality.py +0 -0
  205. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/platform_utils.py +0 -0
  206. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/prng_control.py +0 -0
  207. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/demo_advisor_decisions.py +0 -0
  208. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/example_complete_workflow.py +0 -0
  209. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/generate_focal_report.py +0 -0
  210. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/model_advisor.py +0 -0
  211. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/show_results.py +0 -0
  212. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_adaptive_loss_benchmark.py +0 -0
  213. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_adaptive_training.py +0 -0
  214. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_checkpoint_dict_reconstruction.py +0 -0
  215. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_cls_vs_mean_pooling.py +0 -0
  216. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_confusion_matrix_metadata.py +0 -0
  217. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_data_timestamps.py +0 -0
  218. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_embedding_quality.py +0 -0
  219. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_embedding_space.py +0 -0
  220. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_epoch_class_separation.py +0 -0
  221. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_extend_embedding_space.py +0 -0
  222. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_feature_engineering_prediction.py +0 -0
  223. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_focal_comparison.py +0 -0
  224. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_focal_comparison_enhanced.py +0 -0
  225. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_focal_loss_single_predictor.py +0 -0
  226. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_hybrid_columns.py +0 -0
  227. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_label_smoothing.py +0 -0
  228. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_lift_measurement_validation.py +0 -0
  229. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_lr_timeline_smoothness.py +0 -0
  230. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_min_support_rank_scaling.py +0 -0
  231. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_monitor_integration.py +0 -0
  232. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_multi_dataset.py +0 -0
  233. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_piecewise_epochs.py +0 -0
  234. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_relationship_extractor_integration.py +0 -0
  235. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_relationship_extractor_mixed_types.py +0 -0
  236. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_set_encoder_strategies.py +0 -0
  237. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_temporal_relationships.py +0 -0
  238. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_timeline_quick.py +0 -0
  239. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_training_data_timeline.py +0 -0
  240. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_training_monitor.py +0 -0
  241. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/test_warning_tracking.py +0 -0
  242. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/qa/visualize_training_timeline.py +0 -0
  243. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/relationship_complexity.py +0 -0
  244. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/relationship_extractor.py +0 -0
  245. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/relationship_importance_validator.py +0 -0
  246. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/relationship_performance.py +0 -0
  247. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/relationship_preanalysis.py +0 -0
  248. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/relationship_search.py +0 -0
  249. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/scalar_scalar_ops.py +0 -0
  250. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/scalar_timestamp_ops.py +0 -0
  251. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/schema_history.py +0 -0
  252. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/set_scalar_ops.py +0 -0
  253. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/set_set_ops.py +0 -0
  254. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/set_timestamp_ops.py +0 -0
  255. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/setlist_codec.py +0 -0
  256. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/simple_mlp.py +0 -0
  257. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/single_predictor_mlp.py +0 -0
  258. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/stopwatch.py +0 -0
  259. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/string_list_codec.py +0 -0
  260. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/string_scalar_ops.py +0 -0
  261. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/string_set_ops.py +0 -0
  262. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/temporal_relationship_ops.py +0 -0
  263. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/timeline_events.py +0 -0
  264. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/timestamp_codec.py +0 -0
  265. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/tools/__init__.py +0 -0
  266. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/tools/compare_clusters.py +0 -0
  267. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/training_banner.py +0 -0
  268. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/training_context_manager.py +0 -0
  269. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/training_event.py +0 -0
  270. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/training_exceptions.py +0 -0
  271. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/training_logger.py +0 -0
  272. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/training_movie_writer.py +0 -0
  273. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/training_rules.py +0 -0
  274. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/training_timeline.py +0 -0
  275. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/url_codec.py +0 -0
  276. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/url_ops.py +0 -0
  277. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/url_parser.py +0 -0
  278. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/us_holidays.py +0 -0
  279. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/utils.py +0 -0
  280. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/vector_codec.py +0 -0
  281. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/webhooks.py +0 -0
  282. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/weight_timeline.py +0 -0
  283. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix/neural/world_data.py +0 -0
  284. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/featrix_debug.py +0 -0
  285. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/json_encoder_cache.py +0 -0
  286. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/knn_training.py +0 -0
  287. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/meta_learning_client.py +0 -0
  288. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/model_repair.py +0 -0
  289. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/pre_analysis_wrapper.py +0 -0
  290. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/queue_manager.py +0 -0
  291. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/quick_architecture_search.py +0 -0
  292. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/session_chains.py +0 -0
  293. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/single_predictor_cv.py +0 -0
  294. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/sp_training_wrapper.py +0 -0
  295. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/sphere_config.py +0 -0
  296. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/structureddata.py +0 -0
  297. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/system_health_monitor.py +0 -0
  298. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/training_monitor.py +0 -0
  299. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/utils.py +0 -0
  300. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/lib/webhook_helpers.py +0 -0
  301. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/llm_client.py +0 -0
  302. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/manage_churro.sh +0 -0
  303. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/migrate_string_cache_naming.py +0 -0
  304. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/neural.py +0 -0
  305. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/node-install.sh +0 -0
  306. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/prediction_client.py +0 -0
  307. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/prediction_drift_monitor.py +0 -0
  308. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/prediction_persistence_worker.py +0 -0
  309. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/query_schema_worker.py +0 -0
  310. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/quick_test_deployment.sh +0 -0
  311. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/recreate_session.py +0 -0
  312. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/redis_job_progress.py +0 -0
  313. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/redis_prediction_cli.py +0 -0
  314. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/redis_prediction_store.py +0 -0
  315. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/regenerate_training_movie.py +0 -0
  316. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/render_sphere.py +0 -0
  317. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/repair_checkpoint.py +0 -0
  318. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/repair_model.py +0 -0
  319. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/resubmit_es_completion.py +0 -0
  320. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/run_api_server.sh +0 -0
  321. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/send_email.py +0 -0
  322. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/slack.py +0 -0
  323. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/standalone_prediction.py +0 -0
  324. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/start_celery_cpu_worker.sh +0 -0
  325. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/start_celery_gpu_worker.sh +0 -0
  326. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/start_celery_movie_worker.sh +0 -0
  327. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/tail-watch.py +0 -0
  328. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/test_api_client.py +0 -0
  329. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/tree.py +0 -0
  330. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/upgrade-taco-python312.sh +0 -0
  331. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/utils.py +0 -0
  332. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/src/version.py +0 -0
  333. {featrixsphere-0.2.6379 → featrixsphere-0.2.6710}/tests/test_foundation_mode_local.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: featrixsphere
3
- Version: 0.2.6379
3
+ Version: 0.2.6710
4
4
  Summary: Transform any CSV into a production-ready ML model in minutes, not months.
5
5
  Home-page: https://github.com/Featrix/sphere
6
6
  Author: Featrix
@@ -0,0 +1 @@
1
+ 0.2.6710
@@ -57,7 +57,7 @@ TWO API OPTIONS:
57
57
  >>> print(result['prediction'])
58
58
  """
59
59
 
60
- __version__ = "0.2.6379"
60
+ __version__ = "0.2.6710"
61
61
  __author__ = "Featrix"
62
62
  __email__ = "support@featrix.com"
63
63
  __license__ = "MIT"
@@ -342,6 +342,34 @@ class FeatrixSphere(HTTPClientMixin):
342
342
  ground_truth=ground_truth
343
343
  )
344
344
 
345
+ def list_sessions(
346
+ self,
347
+ name_prefix: str = "",
348
+ ) -> List[str]:
349
+ """
350
+ List sessions matching a name prefix/search term.
351
+
352
+ Searches session directory names on the compute cluster for
353
+ partial matches (not just prefix).
354
+
355
+ Args:
356
+ name_prefix: Term to match in session names
357
+
358
+ Returns:
359
+ List of matching session ID strings
360
+
361
+ Example:
362
+ sessions = featrix.list_sessions(name_prefix="customer")
363
+ for sid in sessions:
364
+ fm = featrix.foundational_model(sid)
365
+ print(f"{sid}: {fm.status}")
366
+ """
367
+ params = {}
368
+ if name_prefix:
369
+ params['name_prefix'] = name_prefix
370
+ response = self._get_json("/compute/sessions-for-org", params=params)
371
+ return response.get('sessions', [])
372
+
345
373
  def health_check(self) -> Dict[str, Any]:
346
374
  """
347
375
  Check if the API server is healthy.
@@ -22,6 +22,21 @@ from .reference_record import ReferenceRecord
22
22
  logger = logging.getLogger(__name__)
23
23
 
24
24
 
25
+ def _parse_datetime(value) -> Optional[datetime]:
26
+ """Parse a datetime from ISO string or return as-is if already datetime."""
27
+ if value is None:
28
+ return None
29
+ if isinstance(value, datetime):
30
+ return value
31
+ if isinstance(value, str):
32
+ try:
33
+ # Handle ISO format with or without timezone
34
+ return datetime.fromisoformat(value.replace('Z', '+00:00'))
35
+ except (ValueError, AttributeError):
36
+ return None
37
+ return None
38
+
39
+
25
40
  @dataclass
26
41
  class FoundationalModel:
27
42
  """
@@ -68,6 +83,11 @@ class FoundationalModel:
68
83
  epochs: Optional[int] = None
69
84
  final_loss: Optional[float] = None
70
85
  created_at: Optional[datetime] = None
86
+ updated_at: Optional[datetime] = None
87
+ session_type: Optional[str] = None
88
+ compute_cluster: Optional[str] = None
89
+ error_message: Optional[str] = None
90
+ training_progress: Optional[Dict[str, Any]] = None
71
91
 
72
92
  # Internal
73
93
  _ctx: Optional['ClientContext'] = field(default=None, repr=False)
@@ -88,7 +108,9 @@ class FoundationalModel:
88
108
  dimensions=response.get('d_model') or response.get('dimensions'),
89
109
  epochs=response.get('epochs') or response.get('final_epoch'),
90
110
  final_loss=response.get('final_loss'),
91
- created_at=datetime.now(),
111
+ created_at=_parse_datetime(response.get('created_at')),
112
+ session_type=response.get('session_type'),
113
+ compute_cluster=response.get('compute_cluster'),
92
114
  _ctx=ctx,
93
115
  )
94
116
 
@@ -99,19 +121,22 @@ class FoundationalModel:
99
121
  ctx: 'ClientContext'
100
122
  ) -> 'FoundationalModel':
101
123
  """Load FoundationalModel from session ID."""
102
- # Get session info
103
- session_data = ctx.get_json(f"/compute/session/{session_id}")
124
+ # Get session info - response has {"session": {...}, "jobs": {...}}
125
+ response_data = ctx.get_json(f"/compute/session/{session_id}")
126
+ session = response_data.get('session', response_data)
104
127
 
105
128
  fm = cls(
106
129
  id=session_id,
107
- name=session_data.get('name'),
108
- status=session_data.get('status'),
109
- created_at=datetime.now(),
130
+ name=session.get('name'),
131
+ status=session.get('status'),
132
+ created_at=_parse_datetime(session.get('created_at')),
133
+ session_type=session.get('session_type'),
134
+ compute_cluster=session.get('compute_cluster'),
110
135
  _ctx=ctx,
111
136
  )
112
137
 
113
- # Try to get model info
114
- fm._update_from_session(session_data)
138
+ # Extract model info, training stats, jobs, error_message
139
+ fm._update_from_session(response_data)
115
140
 
116
141
  return fm
117
142
 
@@ -439,10 +464,11 @@ class FoundationalModel:
439
464
  last_status = None
440
465
 
441
466
  while time.time() - start_time < max_wait_time:
442
- # Get session status
443
- session_data = self._ctx.get_json(f"/compute/session/{self.id}")
467
+ # Get session status - response has {"session": {...}, "jobs": {...}}
468
+ response_data = self._ctx.get_json(f"/compute/session/{self.id}")
469
+ session_data = response_data.get('session', response_data)
444
470
  status = session_data.get('status', 'unknown')
445
- jobs = session_data.get('jobs', {})
471
+ jobs = response_data.get('jobs', {})
446
472
 
447
473
  # Look for ES training job
448
474
  es_job = None
@@ -475,7 +501,7 @@ class FoundationalModel:
475
501
  # Check completion
476
502
  if job_status == 'done' or status == 'done':
477
503
  self.status = 'done'
478
- self._update_from_session(session_data)
504
+ self._update_from_session(response_data)
479
505
  if show_progress:
480
506
  print(f"Training complete!")
481
507
  if self.dimensions:
@@ -566,6 +592,28 @@ class FoundationalModel:
566
592
 
567
593
  return self._ctx.get_json(f"/session/{self.id}/projections")
568
594
 
595
+ def get_sphere_preview(self, save_path: str = None) -> bytes:
596
+ """
597
+ Get the 2D sphere projection preview image (PNG).
598
+
599
+ Args:
600
+ save_path: Optional path to save the PNG file. If provided, the image
601
+ will be written to this path.
602
+
603
+ Returns:
604
+ Raw PNG image bytes.
605
+ """
606
+ if not self._ctx:
607
+ raise ValueError("FoundationalModel not connected to client")
608
+
609
+ png_bytes = self._ctx.get_bytes(f"/session/{self.id}/preview")
610
+
611
+ if save_path:
612
+ with open(save_path, 'wb') as f:
613
+ f.write(png_bytes)
614
+
615
+ return png_bytes
616
+
569
617
  def get_training_metrics(self) -> Dict[str, Any]:
570
618
  """Get training metrics and history."""
571
619
  if not self._ctx:
@@ -605,27 +653,73 @@ class FoundationalModel:
605
653
 
606
654
  return predictors
607
655
 
608
- def _update_from_session(self, session_data: Dict[str, Any]) -> None:
609
- """Update fields from session data."""
610
- # Try to get model info from various places
611
- model_info = session_data.get('model_info', {})
612
- training_stats = session_data.get('training_stats', {})
656
+ def _update_from_session(self, response_data: Dict[str, Any]) -> None:
657
+ """Update fields from session API response.
658
+
659
+ The response from GET /session/{id} has structure:
660
+ {"session": {...}, "jobs": {...}, ...}
661
+ """
662
+ # Handle both nested and flat response formats
663
+ session = response_data.get('session', response_data)
664
+ jobs = response_data.get('jobs', {})
665
+
666
+ # Core session fields
667
+ if session.get('name') and not self.name:
668
+ self.name = session['name']
669
+ if session.get('status'):
670
+ self.status = session['status']
671
+ if session.get('session_type'):
672
+ self.session_type = session['session_type']
673
+ if session.get('compute_cluster'):
674
+ self.compute_cluster = session['compute_cluster']
675
+ if session.get('created_at') and not self.created_at:
676
+ self.created_at = _parse_datetime(session['created_at'])
677
+ if session.get('finished_at'):
678
+ self.updated_at = _parse_datetime(session['finished_at'])
679
+ elif session.get('started_at'):
680
+ self.updated_at = _parse_datetime(session['started_at'])
681
+
682
+ # Model info from session
683
+ model_info = session.get('model_info', {})
684
+ training_stats = session.get('training_stats', {})
613
685
 
614
686
  self.dimensions = (
615
687
  model_info.get('d_model') or
616
688
  model_info.get('embedding_dim') or
617
- session_data.get('d_model')
689
+ session.get('d_model')
618
690
  )
619
691
  self.epochs = (
620
692
  training_stats.get('final_epoch') or
621
693
  training_stats.get('epochs_trained') or
622
- session_data.get('epochs')
694
+ session.get('epochs')
623
695
  )
624
696
  self.final_loss = (
625
697
  training_stats.get('final_loss') or
626
- session_data.get('final_loss')
698
+ session.get('final_loss')
627
699
  )
628
700
 
701
+ # Extract error_message and training_progress from jobs
702
+ for job_id, job in jobs.items():
703
+ job_type = job.get('job_type', '')
704
+ job_status = job.get('status', '')
705
+
706
+ # Training progress from ES training job
707
+ if job_type in ('train_embedding_space', 'train_es', 'training'):
708
+ current_epoch = job.get('current_epoch') or job.get('epoch')
709
+ total_epochs = job.get('total_epochs') or job.get('epochs')
710
+ if current_epoch or total_epochs:
711
+ self.training_progress = {
712
+ 'current_epoch': current_epoch,
713
+ 'total_epochs': total_epochs,
714
+ 'job_status': job_status,
715
+ }
716
+
717
+ # Error message from any failed job
718
+ if job_status in ('failed', 'error'):
719
+ err = job.get('error') or job.get('error_message')
720
+ if err:
721
+ self.error_message = err
722
+
629
723
  def _clean_record(self, record: Dict[str, Any]) -> Dict[str, Any]:
630
724
  """Clean a record for API submission."""
631
725
  import math
@@ -640,6 +734,281 @@ class FoundationalModel:
640
734
  cleaned[key] = value
641
735
  return cleaned
642
736
 
737
+ def get_columns(self) -> List[str]:
738
+ """
739
+ Get the column names in this foundational model's embedding space.
740
+
741
+ Returns:
742
+ List of column name strings
743
+
744
+ Example:
745
+ columns = fm.get_columns()
746
+ print(columns) # ['age', 'income', 'city', ...]
747
+ """
748
+ if not self._ctx:
749
+ raise ValueError("FoundationalModel not connected to client")
750
+
751
+ response = self._ctx.get_json(f"/compute/session/{self.id}/columns")
752
+ return response.get('columns', [])
753
+
754
+ @property
755
+ def columns(self) -> List[str]:
756
+ """Column names in this foundational model's embedding space."""
757
+ return self.get_columns()
758
+
759
+ @property
760
+ def schema_metadata(self) -> Dict[str, Any]:
761
+ """Get schema metadata including column names and types.
762
+
763
+ Returns:
764
+ Dict with 'column_names', 'column_types', and 'num_columns'
765
+ """
766
+ if not self._ctx:
767
+ raise ValueError("FoundationalModel not connected to client")
768
+ return self._ctx.get_json(f"/compute/session/{self.id}/columns")
769
+
770
+ def clone(
771
+ self,
772
+ target_compute_cluster: Optional[str] = None,
773
+ new_name: Optional[str] = None,
774
+ source_compute_cluster: Optional[str] = None,
775
+ ) -> 'FoundationalModel':
776
+ """
777
+ Clone this embedding space, optionally to a different compute node.
778
+
779
+ Args:
780
+ target_compute_cluster: Target compute cluster (None = same node)
781
+ new_name: Name for the cloned session
782
+ source_compute_cluster: Source compute cluster (if routing needed)
783
+
784
+ Returns:
785
+ New FoundationalModel instance for the cloned embedding space
786
+
787
+ Example:
788
+ cloned = fm.clone(
789
+ target_compute_cluster="churro",
790
+ new_name="my-model-clone"
791
+ )
792
+ """
793
+ if not self._ctx:
794
+ raise ValueError("FoundationalModel not connected to client")
795
+
796
+ data = {
797
+ "to_compute": target_compute_cluster,
798
+ "new_session_name": new_name,
799
+ }
800
+
801
+ response = self._ctx.post_json(
802
+ f"/compute/session/{self.id}/clone_embedding_space",
803
+ data=data
804
+ )
805
+
806
+ new_session_id = response.get('new_session_id', '')
807
+ return FoundationalModel(
808
+ id=new_session_id,
809
+ name=new_name,
810
+ status="done",
811
+ created_at=datetime.now(),
812
+ _ctx=self._ctx,
813
+ )
814
+
815
+ def refresh(self) -> Dict[str, Any]:
816
+ """
817
+ Refresh this foundational model's state from the server.
818
+
819
+ Returns the full server-side info for this model, and updates
820
+ local attributes (status, epochs, dimensions, etc.).
821
+
822
+ Returns:
823
+ Full model info dictionary from the server
824
+
825
+ Example:
826
+ info = fm.refresh()
827
+ print(fm.status) # Updated from server
828
+ print(fm.epochs) # Updated from server
829
+ """
830
+ if not self._ctx:
831
+ raise ValueError("FoundationalModel not connected to client")
832
+
833
+ data = self._ctx.get_json(f"/compute/session/{self.id}")
834
+ self._update_from_session(data)
835
+ return data
836
+
837
+ def is_ready(self) -> bool:
838
+ """
839
+ Check if this foundational model has finished training and is ready for use.
840
+
841
+ Returns:
842
+ True if training is complete, False otherwise
843
+
844
+ Example:
845
+ if fm.is_ready():
846
+ predictor = fm.create_classifier(target_column="target")
847
+ """
848
+ if not self._ctx:
849
+ raise ValueError("FoundationalModel not connected to client")
850
+
851
+ data = self._ctx.get_json(f"/compute/session/{self.id}")
852
+ self._update_from_session(data)
853
+ return self.status == 'done'
854
+
855
+ def publish(
856
+ self,
857
+ org_id: str,
858
+ name: Optional[str] = None,
859
+ ) -> Dict[str, Any]:
860
+ """
861
+ Publish this foundational model to the production directory.
862
+
863
+ Published models are protected from garbage collection and available
864
+ across all compute nodes via the shared backplane.
865
+
866
+ Args:
867
+ org_id: Organization ID for directory organization
868
+ name: Name for the published model (defaults to self.name)
869
+
870
+ Returns:
871
+ dict with published_path, output_path, and status
872
+
873
+ Example:
874
+ fm = featrix.create_foundational_model(name="my_model", csv_file="data.csv")
875
+ fm.wait_for_training()
876
+ fm.publish(org_id="my_org", name="my_model_v1")
877
+ """
878
+ if not self._ctx:
879
+ raise ValueError("FoundationalModel not connected to client")
880
+
881
+ publish_name = name or self.name
882
+ if not publish_name:
883
+ raise ValueError("name is required (either pass it or set it on the model)")
884
+
885
+ data = {
886
+ "org_id": org_id,
887
+ "name": publish_name,
888
+ }
889
+ return self._ctx.post_json(f"/compute/session/{self.id}/publish", data=data)
890
+
891
+ def deprecate(
892
+ self,
893
+ warning_message: str,
894
+ expiration_date: str,
895
+ ) -> Dict[str, Any]:
896
+ """
897
+ Deprecate this published model with a warning and expiration date.
898
+
899
+ The model remains available until the expiration date. Prediction
900
+ responses will include a model_expiration field warning consumers.
901
+
902
+ Args:
903
+ warning_message: Warning message to display
904
+ expiration_date: ISO format date string (e.g., "2026-06-01T00:00:00Z")
905
+
906
+ Returns:
907
+ dict with deprecation status
908
+
909
+ Example:
910
+ from datetime import datetime, timedelta
911
+ expiration = (datetime.now() + timedelta(days=90)).isoformat() + "Z"
912
+ fm.deprecate(
913
+ warning_message="Replaced by v2. Migrate by expiration.",
914
+ expiration_date=expiration
915
+ )
916
+ """
917
+ if not self._ctx:
918
+ raise ValueError("FoundationalModel not connected to client")
919
+
920
+ data = {
921
+ "warning_message": warning_message,
922
+ "expiration_date": expiration_date,
923
+ }
924
+ return self._ctx.post_json(f"/compute/session/{self.id}/deprecate", data=data)
925
+
926
+ def unpublish(self) -> Dict[str, Any]:
927
+ """
928
+ Unpublish this model, moving it back from the published directory.
929
+
930
+ WARNING: After unpublishing, the model is subject to garbage
931
+ collection and may be deleted when disk space is low.
932
+
933
+ Returns:
934
+ dict with unpublish status
935
+
936
+ Example:
937
+ fm.unpublish()
938
+ """
939
+ if not self._ctx:
940
+ raise ValueError("FoundationalModel not connected to client")
941
+
942
+ return self._ctx.post_json(f"/compute/session/{self.id}/unpublish", data={})
943
+
944
+ def publish_checkpoint(
945
+ self,
946
+ name: str,
947
+ org_id: Optional[str] = None,
948
+ checkpoint_epoch: Optional[int] = None,
949
+ session_name_prefix: Optional[str] = None,
950
+ publish: bool = True,
951
+ ) -> 'FoundationalModel':
952
+ """
953
+ Publish a checkpoint from this model's training as a new foundation model.
954
+
955
+ Creates a NEW FoundationalModel from a training checkpoint with full
956
+ provenance tracking. Useful for snapshotting good intermediate models
957
+ while training continues.
958
+
959
+ Args:
960
+ name: Name for the new foundation model (required)
961
+ org_id: Organization ID (required if publish=True)
962
+ checkpoint_epoch: Which epoch checkpoint to use (None = best/latest)
963
+ session_name_prefix: Optional prefix for the new session ID
964
+ publish: Move to published directory (default: True)
965
+
966
+ Returns:
967
+ New FoundationalModel instance for the published checkpoint
968
+
969
+ Example:
970
+ # Snapshot epoch 50 while training continues
971
+ checkpoint_fm = fm.publish_checkpoint(
972
+ name="My Model v0.5",
973
+ org_id="my_org",
974
+ checkpoint_epoch=50
975
+ )
976
+ # Use immediately
977
+ predictor = checkpoint_fm.create_classifier(target_column="target")
978
+ """
979
+ if not self._ctx:
980
+ raise ValueError("FoundationalModel not connected to client")
981
+
982
+ if publish and not org_id:
983
+ raise ValueError("org_id is required when publish=True")
984
+
985
+ data = {
986
+ "name": name,
987
+ "publish": publish,
988
+ }
989
+ if checkpoint_epoch is not None:
990
+ data["checkpoint_epoch"] = checkpoint_epoch
991
+ if session_name_prefix:
992
+ data["session_name_prefix"] = session_name_prefix
993
+ if org_id:
994
+ data["org_id"] = org_id
995
+
996
+ response = self._ctx.post_json(
997
+ f"/compute/session/{self.id}/publish_partial_foundation",
998
+ data=data
999
+ )
1000
+
1001
+ new_fm = FoundationalModel(
1002
+ id=response.get("foundation_session_id", ""),
1003
+ name=name,
1004
+ status="done",
1005
+ epochs=response.get("checkpoint_epoch"),
1006
+ created_at=datetime.now(),
1007
+ _ctx=self._ctx,
1008
+ )
1009
+
1010
+ return new_fm
1011
+
643
1012
  def to_dict(self) -> Dict[str, Any]:
644
1013
  """Convert to dictionary representation."""
645
1014
  return {
@@ -650,6 +1019,11 @@ class FoundationalModel:
650
1019
  'epochs': self.epochs,
651
1020
  'final_loss': self.final_loss,
652
1021
  'created_at': self.created_at.isoformat() if self.created_at else None,
1022
+ 'updated_at': self.updated_at.isoformat() if self.updated_at else None,
1023
+ 'session_type': self.session_type,
1024
+ 'compute_cluster': self.compute_cluster,
1025
+ 'error_message': self.error_message,
1026
+ 'training_progress': self.training_progress,
653
1027
  }
654
1028
 
655
1029
  def __repr__(self) -> str:
@@ -121,14 +121,34 @@ class HTTPClientMixin:
121
121
 
122
122
  def _unwrap_response(self, response_json: Dict[str, Any]) -> Dict[str, Any]:
123
123
  """
124
- Unwrap server response, handling the 'response' wrapper if present.
124
+ Unwrap server response, handling wrapper formats.
125
125
 
126
- The server sometimes wraps responses in {"response": {...}}.
126
+ The server may wrap responses as:
127
+ - {"response": {...}}
128
+ - {"_meta": {...}, "data": {...}}
129
+
130
+ Captures server metadata when present.
127
131
  """
128
- if isinstance(response_json, dict) and 'response' in response_json and len(response_json) == 1:
129
- return response_json['response']
132
+ if isinstance(response_json, dict):
133
+ # Handle _meta/data wrapper (captures server metadata)
134
+ if '_meta' in response_json and 'data' in response_json:
135
+ self._last_server_metadata = response_json['_meta']
136
+ return response_json['data']
137
+ # Handle response wrapper
138
+ if 'response' in response_json and len(response_json) == 1:
139
+ return response_json['response']
130
140
  return response_json
131
141
 
142
+ @property
143
+ def last_server_metadata(self) -> Optional[Dict[str, Any]]:
144
+ """
145
+ Metadata from the most recent server response.
146
+
147
+ Contains server info like compute_cluster_time, compute_cluster,
148
+ compute_cluster_version, etc.
149
+ """
150
+ return getattr(self, '_last_server_metadata', None)
151
+
132
152
  def _get_json(
133
153
  self,
134
154
  endpoint: str,
@@ -139,6 +159,16 @@ class HTTPClientMixin:
139
159
  response = self._make_request("GET", endpoint, max_retries=max_retries, **kwargs)
140
160
  return self._unwrap_response(response.json())
141
161
 
162
+ def _get_bytes(
163
+ self,
164
+ endpoint: str,
165
+ max_retries: Optional[int] = None,
166
+ **kwargs
167
+ ) -> bytes:
168
+ """Make a GET request and return raw bytes (for binary content like images)."""
169
+ response = self._make_request("GET", endpoint, max_retries=max_retries, **kwargs)
170
+ return response.content
171
+
142
172
  def _post_json(
143
173
  self,
144
174
  endpoint: str,
@@ -207,3 +237,6 @@ class ClientContext:
207
237
  def post_multipart(self, endpoint: str, data: Dict[str, Any] = None,
208
238
  files: Dict[str, Any] = None, **kwargs) -> Dict[str, Any]:
209
239
  return self._client._post_multipart(endpoint, data, files, **kwargs)
240
+
241
+ def get_bytes(self, endpoint: str, **kwargs) -> bytes:
242
+ return self._client._get_bytes(endpoint, **kwargs)