agi-env 2025.12.19__tar.gz → 2026.2.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 (32) hide show
  1. {agi_env-2025.12.19/src/agi_env.egg-info → agi_env-2026.2.6}/PKG-INFO +3 -3
  2. {agi_env-2025.12.19 → agi_env-2026.2.6}/README.md +1 -1
  3. {agi_env-2025.12.19 → agi_env-2026.2.6}/pyproject.toml +3 -2
  4. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/agi_env.py +86 -13
  5. {agi_env-2025.12.19 → agi_env-2026.2.6/src/agi_env.egg-info}/PKG-INFO +3 -3
  6. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env.egg-info/SOURCES.txt +0 -2
  7. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env.egg-info/requires.txt +1 -1
  8. {agi_env-2025.12.19 → agi_env-2026.2.6}/test/test_agi_env.py +2 -0
  9. agi_env-2025.12.19/src/agi_env/resources/.DS_Store +0 -0
  10. agi_env-2025.12.19/src/agi_env/resources/mistral_offline/.DS_Store +0 -0
  11. {agi_env-2025.12.19 → agi_env-2026.2.6}/LICENSE +0 -0
  12. {agi_env-2025.12.19 → agi_env-2026.2.6}/MANIFEST.in +0 -0
  13. {agi_env-2025.12.19 → agi_env-2026.2.6}/setup.cfg +0 -0
  14. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/__init__.py +0 -0
  15. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/__init__.py +0 -0
  16. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/agi_logger.py +0 -0
  17. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/app_args.py +0 -0
  18. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/defaults.py +0 -0
  19. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/pagelib.py +0 -0
  20. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/resources/.agilab/.env +0 -0
  21. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/resources/.agilab/balancer_df.csv +0 -0
  22. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/resources/.agilab/balancer_model.pkl +0 -0
  23. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/resources/mistral_offline/README.md +0 -0
  24. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/resources/mistral_offline/data/.gitignore +0 -0
  25. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/resources/mistral_offline/data/.gitkeep +0 -0
  26. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env/streamlit_args.py +0 -0
  27. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env.egg-info/dependency_links.txt +0 -0
  28. {agi_env-2025.12.19 → agi_env-2026.2.6}/src/agi_env.egg-info/top_level.txt +0 -0
  29. {agi_env-2025.12.19 → agi_env-2026.2.6}/test/test_app_args.py +0 -0
  30. {agi_env-2025.12.19 → agi_env-2026.2.6}/test/test_pagelib.py +0 -0
  31. {agi_env-2025.12.19 → agi_env-2026.2.6}/test/test_streamlit_args.py +0 -0
  32. {agi_env-2025.12.19 → agi_env-2026.2.6}/uv_config.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agi-env
3
- Version: 2025.12.19
3
+ Version: 2026.2.6
4
4
  Summary: AGI Env
5
5
  Author-email: Jean-Pierre Morard <focus@thalesgroup.com>
6
6
  Project-URL: Documentation, https://thalesgroup.github.io/agilab
@@ -30,11 +30,11 @@ Requires-Dist: pathspec
30
30
  Requires-Dist: ipython
31
31
  Requires-Dist: py7zr
32
32
  Requires-Dist: cmake>=3.29
33
- Requires-Dist: numba
33
+ Requires-Dist: numba>=0.61.0
34
34
  Requires-Dist: streamlit
35
35
  Dynamic: license-file
36
36
 
37
- [![PyPI version](https://img.shields.io/badge/PyPI-2025.12.19.post1-informational?logo=pypi)](https://pypi.org/project/agi-env)
37
+ [![PyPI version](https://img.shields.io/badge/PyPI-2025.12.19-informational?logo=pypi)](https://pypi.org/project/agi-env)
38
38
  [![Supported Python Versions](https://img.shields.io/pypi/pyversions/agilab.svg)](https://pypi.org/project/agilab/)
39
39
  [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
40
40
  [![pypi_dl](https://img.shields.io/pypi/dm/agilab)]()
@@ -1,4 +1,4 @@
1
- [![PyPI version](https://img.shields.io/badge/PyPI-2025.12.19.post1-informational?logo=pypi)](https://pypi.org/project/agi-env)
1
+ [![PyPI version](https://img.shields.io/badge/PyPI-2025.12.19-informational?logo=pypi)](https://pypi.org/project/agi-env)
2
2
  [![Supported Python Versions](https://img.shields.io/pypi/pyversions/agilab.svg)](https://pypi.org/project/agilab/)
3
3
  [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
4
4
  [![pypi_dl](https://img.shields.io/pypi/dm/agilab)]()
@@ -1,5 +1,5 @@
1
1
  [project]
2
- version = "2025.12.19"
2
+ version = "2026.02.06"
3
3
  name = "agi-env"
4
4
  description = "AGI Env"
5
5
  requires-python = ">=3.11"
@@ -39,7 +39,7 @@ dependencies = [
39
39
  "ipython",
40
40
  "py7zr",
41
41
  "cmake>=3.29",
42
- "numba",
42
+ "numba>=0.61.0",
43
43
  "streamlit"
44
44
  ]
45
45
  [project.urls]
@@ -92,6 +92,7 @@ Tracker = "https://github.com/ThalesGroup/agilab/issues"
92
92
 
93
93
 
94
94
 
95
+
95
96
 
96
97
 
97
98
  [dependency-groups]
@@ -501,6 +501,7 @@ class AgiEnv(metaclass=_AgiEnvMeta):
501
501
  env_path = self.resources_path / ".env"
502
502
  self.benchmark = self.resources_path / "benchmark.json"
503
503
  self.envars = dotenv_values(dotenv_path=env_path, verbose=verbose)
504
+ logger.debug(f"env path: {env_path}")
504
505
  envars = self.envars
505
506
  repo_agilab_dir = Path(__file__).resolve().parents[4]
506
507
 
@@ -948,8 +949,76 @@ class AgiEnv(metaclass=_AgiEnvMeta):
948
949
  self.uv_worker = self.uv
949
950
  use_freethread = False
950
951
 
951
- self.AGI_LOCAL_SHARE = envars.get("AGI_LOCAL_SHARE", 'localshare')
952
- self.AGI_CLUSTER_SHARE = envars.get("AGI_CLUSTER_SHARE", 'clustershare')
952
+ self.AGI_LOCAL_SHARE = envars.get("AGI_LOCAL_SHARE", "localshare")
953
+ self.AGI_CLUSTER_SHARE = envars.get("AGI_CLUSTER_SHARE", "clustershare")
954
+
955
+ # `AGI_SHARE_DIR` is the user-facing knob (installer + Streamlit UI). Treat it
956
+ # as an override for the cluster share root so updating it is immediately
957
+ # reflected without having to also edit `AGI_CLUSTER_SHARE` manually.
958
+ share_dir_override = envars.get("AGI_SHARE_DIR")
959
+ if share_dir_override is not None:
960
+ share_dir_value = str(share_dir_override).strip()
961
+ if share_dir_value:
962
+ self.AGI_CLUSTER_SHARE = share_dir_value
963
+ try:
964
+ envars["AGI_CLUSTER_SHARE"] = share_dir_value
965
+ except Exception:
966
+ pass
967
+
968
+ def _cluster_enabled_from_settings() -> bool:
969
+ """Best-effort read of the Streamlit 'Enable Cluster' toggle.
970
+
971
+ The toggle is persisted under `[cluster].cluster_enabled` in each app's
972
+ `app_settings.toml`. When the per-app setting is missing, fall back to
973
+ the global `.env` value `AGI_CLUSTER_ENABLED` if present.
974
+ """
975
+
976
+ if self.is_worker_env:
977
+ return True
978
+
979
+ def _parse_bool(value: object) -> bool | None:
980
+ if isinstance(value, bool):
981
+ return value
982
+ if isinstance(value, (int, float)):
983
+ return bool(value)
984
+ if isinstance(value, str):
985
+ normalized = value.strip().lower()
986
+ if normalized in {"1", "true", "yes", "y", "on"}:
987
+ return True
988
+ if normalized in {"0", "false", "no", "n", "off", ""}:
989
+ return False
990
+ return None
991
+
992
+ parsed: bool | None = None
993
+
994
+ try:
995
+ settings_path = self.app_src / "app_settings.toml"
996
+ except Exception:
997
+ settings_path = None
998
+
999
+ try:
1000
+ if (
1001
+ settings_path is not None
1002
+ and settings_path.exists()
1003
+ and settings_path.stat().st_size > 0
1004
+ ):
1005
+ import tomllib
1006
+
1007
+ with settings_path.open("rb") as handle:
1008
+ doc = tomllib.load(handle)
1009
+ cluster_section = doc.get("cluster")
1010
+ if isinstance(cluster_section, dict) and "cluster_enabled" in cluster_section:
1011
+ parsed = _parse_bool(cluster_section.get("cluster_enabled"))
1012
+ except Exception:
1013
+ parsed = None
1014
+
1015
+ if parsed is not None:
1016
+ return parsed
1017
+
1018
+ parsed = _parse_bool(envars.get("AGI_CLUSTER_ENABLED"))
1019
+ return bool(parsed) if parsed is not None else False
1020
+
1021
+ cluster_enabled = _cluster_enabled_from_settings()
953
1022
 
954
1023
  def _abs_path(path_str: str) -> str:
955
1024
  """Absolute path; relative paths are relative to $HOME."""
@@ -1042,24 +1111,28 @@ class AgiEnv(metaclass=_AgiEnvMeta):
1042
1111
 
1043
1112
  # No bind rule found; directory is usable, so accept it.
1044
1113
  return True
1045
-
1046
1114
  candidate = _abs_path(self.AGI_CLUSTER_SHARE)
1047
- if is_mounted(candidate):
1115
+
1116
+ wants_cluster_share = bool(cluster_enabled)
1117
+ mounted = is_mounted(candidate)
1118
+ if mounted and wants_cluster_share:
1048
1119
  self.agi_share_path = self.AGI_CLUSTER_SHARE
1049
1120
  #AgiEnv.logger.info(
1050
1121
  # f"self.agi_share_path = AGI_CLUSTER_SHARE = {candidate}"
1051
1122
  #)
1052
1123
  else:
1053
1124
  self.agi_share_path = self.AGI_LOCAL_SHARE
1054
- fallback = _abs_path(self.AGI_LOCAL_SHARE)
1055
- warning_key = (candidate, fallback)
1056
- if warning_key not in AgiEnv._share_mount_warning_keys:
1057
- AgiEnv._share_mount_warning_keys.add(warning_key)
1058
- AgiEnv.logger.warning(
1059
- "AGI_CLUSTER_SHARE is not mounted at %s; using AGI_LOCAL_SHARE=%s",
1060
- candidate,
1061
- fallback,
1062
- )
1125
+ if wants_cluster_share and not mounted:
1126
+ fallback = _abs_path(self.AGI_LOCAL_SHARE)
1127
+ warning_key = (candidate, fallback)
1128
+ if warning_key not in AgiEnv._share_mount_warning_keys:
1129
+ AgiEnv._share_mount_warning_keys.add(warning_key)
1130
+ AgiEnv.logger.warning(
1131
+ "Cluster is enabled but AGI_CLUSTER_SHARE is not mounted at %s; using AGI_LOCAL_SHARE=%s; using env=%s",
1132
+ candidate,
1133
+ fallback,
1134
+ env_path
1135
+ )
1063
1136
  self._share_root_cache = None
1064
1137
 
1065
1138
  share_root_abs = self.share_root_path()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agi-env
3
- Version: 2025.12.19
3
+ Version: 2026.2.6
4
4
  Summary: AGI Env
5
5
  Author-email: Jean-Pierre Morard <focus@thalesgroup.com>
6
6
  Project-URL: Documentation, https://thalesgroup.github.io/agilab
@@ -30,11 +30,11 @@ Requires-Dist: pathspec
30
30
  Requires-Dist: ipython
31
31
  Requires-Dist: py7zr
32
32
  Requires-Dist: cmake>=3.29
33
- Requires-Dist: numba
33
+ Requires-Dist: numba>=0.61.0
34
34
  Requires-Dist: streamlit
35
35
  Dynamic: license-file
36
36
 
37
- [![PyPI version](https://img.shields.io/badge/PyPI-2025.12.19.post1-informational?logo=pypi)](https://pypi.org/project/agi-env)
37
+ [![PyPI version](https://img.shields.io/badge/PyPI-2025.12.19-informational?logo=pypi)](https://pypi.org/project/agi-env)
38
38
  [![Supported Python Versions](https://img.shields.io/pypi/pyversions/agilab.svg)](https://pypi.org/project/agilab/)
39
39
  [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
40
40
  [![pypi_dl](https://img.shields.io/pypi/dm/agilab)]()
@@ -16,11 +16,9 @@ src/agi_env.egg-info/SOURCES.txt
16
16
  src/agi_env.egg-info/dependency_links.txt
17
17
  src/agi_env.egg-info/requires.txt
18
18
  src/agi_env.egg-info/top_level.txt
19
- src/agi_env/resources/.DS_Store
20
19
  src/agi_env/resources/.agilab/.env
21
20
  src/agi_env/resources/.agilab/balancer_df.csv
22
21
  src/agi_env/resources/.agilab/balancer_model.pkl
23
- src/agi_env/resources/mistral_offline/.DS_Store
24
22
  src/agi_env/resources/mistral_offline/README.md
25
23
  src/agi_env/resources/mistral_offline/data/.gitignore
26
24
  src/agi_env/resources/mistral_offline/data/.gitkeep
@@ -9,5 +9,5 @@ pathspec
9
9
  ipython
10
10
  py7zr
11
11
  cmake>=3.29
12
- numba
12
+ numba>=0.61.0
13
13
  streamlit
@@ -86,6 +86,8 @@ def test_cluster_share_warning_deduplicated(tmp_path: Path, monkeypatch):
86
86
  agipath = AgiEnv.locate_agilab_installation(verbose=False)
87
87
  fake_home = tmp_path / "fake_home"
88
88
  fake_home.mkdir()
89
+ (fake_home / ".agilab").mkdir(parents=True, exist_ok=True)
90
+ (fake_home / ".agilab" / ".env").write_text("AGI_CLUSTER_ENABLED=1\n")
89
91
  share_dir = fake_home / ".local" / "share" / "agilab"
90
92
  share_dir.mkdir(parents=True, exist_ok=True)
91
93
  (share_dir / ".agilab-path").write_text(str(agipath) + "\n")
File without changes
File without changes
File without changes
File without changes
File without changes