diff --git a/src/langbot/pkg/box/service.py b/src/langbot/pkg/box/service.py index ea117b0cc..ca30eb930 100644 --- a/src/langbot/pkg/box/service.py +++ b/src/langbot/pkg/box/service.py @@ -82,7 +82,6 @@ class BoxService: return self._enabled async def initialize(self): - self._ensure_default_workspace() if not self._enabled: # Disabled by config: do NOT connect to a remote runtime, do NOT # fork a stdio subprocess. Every consumer of box_service should @@ -99,6 +98,7 @@ class BoxService: await self._runtime_connector.initialize() else: await self.client.initialize() + self._ensure_default_workspace() self._available = True self._connector_error = '' self.ap.logger.info( @@ -1152,6 +1152,9 @@ class BoxService: if self.default_workspace is None: return + if not self.shares_filesystem_with_box: + return + if os.path.isdir(self.default_workspace): return @@ -1176,7 +1179,7 @@ class BoxService: return host_path = os.path.realpath(spec.host_path) - if not os.path.isdir(host_path): + if self.shares_filesystem_with_box and not os.path.isdir(host_path): raise BoxValidationError('host_path must point to an existing directory on the host') if not self.allowed_mount_roots: diff --git a/tests/unit_tests/box/test_box_service.py b/tests/unit_tests/box/test_box_service.py index acf53264f..4d66ec8f8 100644 --- a/tests/unit_tests/box/test_box_service.py +++ b/tests/unit_tests/box/test_box_service.py @@ -256,6 +256,31 @@ class TestSharesFilesystemWithBox: assert service.shares_filesystem_with_box is False +def test_separated_box_runtime_does_not_create_default_workspace_in_langbot(tmp_path): + logger = Mock() + runtime = BoxRuntime(logger=logger, backends=[FakeBackend(logger)], session_ttl_sec=300) + host_root = tmp_path / 'box' + service = BoxService(make_app(logger, host_root=str(host_root)), client=_InProcessBoxRuntimeClient(logger, runtime)) + service._shares_filesystem_with_box_override = False + + service._ensure_default_workspace() + + assert not (host_root / 'default').exists() + + +def test_separated_box_runtime_allows_box_owned_missing_host_path(tmp_path): + logger = Mock() + runtime = BoxRuntime(logger=logger, backends=[FakeBackend(logger)], session_ttl_sec=300) + host_root = tmp_path / 'box' + service = BoxService(make_app(logger, host_root=str(host_root)), client=_InProcessBoxRuntimeClient(logger, runtime)) + service._shares_filesystem_with_box_override = False + + spec = service.build_spec({'cmd': 'echo hi', 'session_id': 'missing-host-path'}) + + assert spec.host_path == str(host_root / 'default') + assert not (host_root / 'default').exists() + + @pytest.mark.asyncio async def test_box_service_get_sessions_delegates_to_client(): client = Mock() @@ -500,6 +525,7 @@ async def test_box_service_creates_default_workspace_on_initialize(tmp_path): app = make_app(logger, [str(allowed_root)]) app.instance_config.data['box']['local']['default_workspace'] = str(default_workspace) service = BoxService(app, client=_InProcessBoxRuntimeClient(logger, runtime)) + service._shares_filesystem_with_box_override = True await service.initialize() @@ -514,6 +540,7 @@ async def test_box_service_derives_workspace_and_allowed_root_from_host_root(tmp shared_root = tmp_path / 'shared-box-root' app = make_app(logger, host_root=str(shared_root)) service = BoxService(app, client=_InProcessBoxRuntimeClient(logger, runtime)) + service._shares_filesystem_with_box_override = True await service.initialize()