refactor(box): remove legacy in-process runtime code and clean up smells

After the architecture settled on always using an independent Box Runtime
service, several pieces of compatibility code and design shortcuts were
left behind. This commit cleans them up:

- Remove `LocalBoxRuntimeClient` and `create_box_runtime_client` from
  production code (moved to test-only helper).
- Remove unused `_clip_bytes` method from backend.
- Remove `__langbot_session_placeholder__` hack by making `BoxSpec.cmd`
  default to empty and validating non-empty only in `runtime.execute()`.
- Extract `get_box_config()` helper to eliminate 5× duplicated config
  access boilerplate.
- Remove `session_id`/`host_path`/`host_path_mode` from the LLM-facing
  tool schema to enforce request-scoped session isolation.
- Fix dual shutdown path: `NativeToolLoader.shutdown()` no longer calls
  `box_service.shutdown()` (handled by `Application.dispose()`).
- Simplify `_assert_session_compatible` with a loop.
- Inline client creation in `BoxRuntimeConnector`.
- Remove redundant `BOX__RUNTIME_URL` env var from docker-compose
  (auto-detected by code).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
youhuanghe
2026-03-20 12:04:39 +00:00
committed by WangCham
parent eaae31edd0
commit 6391678fdb
11 changed files with 98 additions and 161 deletions
+4 -10
View File
@@ -12,7 +12,7 @@ import pydantic
from .client import BoxRuntimeClient
from .connector import BoxRuntimeConnector
from .errors import BoxError, BoxValidationError
from .models import BUILTIN_PROFILES, BoxExecutionResult, BoxProfile, BoxSpec
from .models import BUILTIN_PROFILES, BoxExecutionResult, BoxProfile, BoxSpec, get_box_config
_INT_ADAPTER = pydantic.TypeAdapter(int)
_UTC = _dt.timezone.utc
@@ -189,9 +189,7 @@ class BoxService:
}
def _load_allowed_host_mount_roots(self) -> list[str]:
box_config = getattr(self.ap, 'instance_config', None)
box_config_data = getattr(box_config, 'data', {}) if box_config is not None else {}
configured_roots = box_config_data.get('box', {}).get('allowed_host_mount_roots', [])
configured_roots = get_box_config(self.ap).get('allowed_host_mount_roots', [])
normalized_roots: list[str] = []
for root in configured_roots:
@@ -203,9 +201,7 @@ class BoxService:
return normalized_roots
def _load_default_host_workspace(self) -> str | None:
box_config = getattr(self.ap, 'instance_config', None)
box_config_data = getattr(box_config, 'data', {}) if box_config is not None else {}
default_host_workspace = str(box_config_data.get('box', {}).get('default_host_workspace', '')).strip()
default_host_workspace = str(get_box_config(self.ap).get('default_host_workspace', '')).strip()
if not default_host_workspace:
return None
return os.path.realpath(os.path.abspath(default_host_workspace))
@@ -252,9 +248,7 @@ class BoxService:
raise BoxValidationError(f'host_path is outside allowed_host_mount_roots: {allowed_roots}')
def _load_profile(self) -> BoxProfile:
box_config = getattr(self.ap, 'instance_config', None)
box_config_data = getattr(box_config, 'data', {}) if box_config is not None else {}
profile_name = str(box_config_data.get('box', {}).get('profile', 'default')).strip() or 'default'
profile_name = str(get_box_config(self.ap).get('profile', 'default')).strip() or 'default'
profile = BUILTIN_PROFILES.get(profile_name)
if profile is None: