Implemented the next missing parity slice around session env var subprocess merging.
Wires session_env_vars.py into agent_tools._build_subprocess_env so that variables set via the session registry now reach spawned children, matching utils/shell/bashProvider.ts:249. Per-call extra_env still wins so explicit tool overrides take precedence over session defaults.
This commit is contained in:
+1
-1
@@ -707,7 +707,7 @@ Done:
|
|||||||
- [x] Basic git status snapshot
|
- [x] Basic git status snapshot
|
||||||
- [x] Basic shell/subprocess handling
|
- [x] Basic shell/subprocess handling
|
||||||
- [x] Bundled small portable utilities — `utils/array.ts`, `utils/set.ts`, `utils/objectGroupBy.ts`, `utils/xml.ts`, `utils/uuid.ts` ported in `src/small_utils.py`
|
- [x] Bundled small portable utilities — `utils/array.ts`, `utils/set.ts`, `utils/objectGroupBy.ts`, `utils/xml.ts`, `utils/uuid.ts` ported in `src/small_utils.py`
|
||||||
- [x] Session-scoped env-var registry (`utils/sessionEnvVars.ts`) ported in `src/session_env_vars.py`
|
- [x] Session-scoped env-var registry (`utils/sessionEnvVars.ts`) ported in `src/session_env_vars.py` and merged into spawned subprocess env via `_build_subprocess_env` (mirrors `utils/shell/bashProvider.ts`)
|
||||||
- [x] Display formatters from `utils/format.ts` (`formatFileSize`, `formatSecondsShort`, `formatDuration`, `formatNumber`, `formatTokens`) ported in `src/format_utils.py`
|
- [x] Display formatters from `utils/format.ts` (`formatFileSize`, `formatSecondsShort`, `formatDuration`, `formatNumber`, `formatTokens`) ported in `src/format_utils.py`
|
||||||
|
|
||||||
Missing major utility categories:
|
Missing major utility categories:
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from pathlib import Path
|
|||||||
from typing import TYPE_CHECKING, Any, Callable, Iterator, Union
|
from typing import TYPE_CHECKING, Any, Callable, Iterator, Union
|
||||||
|
|
||||||
from .agent_types import AgentPermissions, AgentRuntimeConfig, ToolExecutionResult
|
from .agent_types import AgentPermissions, AgentRuntimeConfig, ToolExecutionResult
|
||||||
|
from .session_env_vars import get_session_env_vars
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .account_runtime import AccountRuntime
|
from .account_runtime import AccountRuntime
|
||||||
@@ -3321,6 +3322,11 @@ def _build_subprocess_env(context: ToolExecutionContext) -> dict[str, str]:
|
|||||||
for key, value in os.environ.items()
|
for key, value in os.environ.items()
|
||||||
if not _is_sensitive_env_var(key)
|
if not _is_sensitive_env_var(key)
|
||||||
}
|
}
|
||||||
|
# Mirror utils/shell/bashProvider.ts: session env vars (set via /env)
|
||||||
|
# apply to spawned children, layered above the parent env but below
|
||||||
|
# explicit per-call extras.
|
||||||
|
for key, value in get_session_env_vars().items():
|
||||||
|
env[key] = value
|
||||||
env.update(context.extra_env)
|
env.update(context.extra_env)
|
||||||
return env
|
return env
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from pathlib import Path
|
|||||||
from src.agent_tools import (
|
from src.agent_tools import (
|
||||||
ToolExecutionError,
|
ToolExecutionError,
|
||||||
ToolPermissionError,
|
ToolPermissionError,
|
||||||
|
_build_subprocess_env,
|
||||||
_ensure_shell_allowed,
|
_ensure_shell_allowed,
|
||||||
_is_sensitive_env_var,
|
_is_sensitive_env_var,
|
||||||
_resolve_path,
|
_resolve_path,
|
||||||
@@ -16,6 +17,10 @@ from src.agent_tools import (
|
|||||||
default_tool_registry,
|
default_tool_registry,
|
||||||
)
|
)
|
||||||
from src.agent_types import AgentPermissions, AgentRuntimeConfig
|
from src.agent_types import AgentPermissions, AgentRuntimeConfig
|
||||||
|
from src.session_env_vars import (
|
||||||
|
clear_session_env_vars,
|
||||||
|
set_session_env_var,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _make_context(
|
def _make_context(
|
||||||
@@ -230,5 +235,35 @@ class TestIsSensitiveEnvVar(unittest.TestCase):
|
|||||||
self.assertTrue(_is_sensitive_env_var("db_password"))
|
self.assertTrue(_is_sensitive_env_var("db_password"))
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# _build_subprocess_env – session env var merging
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
class TestBuildSubprocessEnv(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
clear_session_env_vars()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
clear_session_env_vars()
|
||||||
|
|
||||||
|
def test_session_env_var_appears_in_subprocess_env(self):
|
||||||
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
|
ctx = _make_context(tmp)
|
||||||
|
set_session_env_var("CLAW_SESSION_FOO", "from-session")
|
||||||
|
env = _build_subprocess_env(ctx)
|
||||||
|
self.assertEqual(env["CLAW_SESSION_FOO"], "from-session")
|
||||||
|
|
||||||
|
def test_extra_env_overrides_session_env(self):
|
||||||
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
|
config = AgentRuntimeConfig(cwd=Path(tmp))
|
||||||
|
ctx = build_tool_context(
|
||||||
|
config,
|
||||||
|
tool_registry=default_tool_registry(),
|
||||||
|
extra_env={"CLAW_OVERRIDE_ME": "from-extra"},
|
||||||
|
)
|
||||||
|
set_session_env_var("CLAW_OVERRIDE_ME", "from-session")
|
||||||
|
env = _build_subprocess_env(ctx)
|
||||||
|
self.assertEqual(env["CLAW_OVERRIDE_ME"], "from-extra")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user