From 5a4ec62b14c6faf119945674b3b04a4e27291a00 Mon Sep 17 00:00:00 2001 From: Junyan Qin Date: Sat, 18 Apr 2026 22:40:32 +0800 Subject: [PATCH] feat(box): support custom sandbox container image via config.yaml Add 'image' field to box config section. When set, it overrides the profile default image (python:3.11-slim) for all sandbox containers. Priority: caller-specified > config.yaml image > profile default. --- src/langbot/pkg/box/service.py | 9 +++++++++ src/langbot/templates/config.yaml | 1 + 2 files changed, 10 insertions(+) diff --git a/src/langbot/pkg/box/service.py b/src/langbot/pkg/box/service.py index 77abda00..cf41d789 100644 --- a/src/langbot/pkg/box/service.py +++ b/src/langbot/pkg/box/service.py @@ -60,6 +60,7 @@ class BoxService: self.allowed_host_mount_roots = self._load_allowed_host_mount_roots() self.default_host_workspace = self._load_default_host_workspace() self.profile = self._load_profile() + self.custom_image = self._load_custom_image() self.workspace_quota_mb = self._load_workspace_quota_mb() self._recent_errors: collections.deque[dict] = collections.deque(maxlen=_MAX_RECENT_ERRORS) self._shutdown_task = None @@ -209,6 +210,10 @@ class BoxService: if spec_payload.get('workspace_quota_mb') in (None, '') and self.workspace_quota_mb is not None: spec_payload['workspace_quota_mb'] = self.workspace_quota_mb + # Global custom image overrides profile default (but not caller-specified image) + if self.custom_image and 'image' not in spec_payload: + spec_payload['image'] = self.custom_image + self._apply_profile(spec_payload) try: @@ -360,6 +365,10 @@ class BoxService: default_host_workspace = os.path.join(self.shared_host_root, 'default') return os.path.realpath(os.path.abspath(default_host_workspace)) + def _load_custom_image(self) -> str | None: + raw = str(_get_box_config(self.ap).get('image', '') or '').strip() + return raw or None + def _load_workspace_quota_mb(self) -> int | None: raw_value = _get_box_config(self.ap).get('workspace_quota_mb') if raw_value in (None, ''): diff --git a/src/langbot/templates/config.yaml b/src/langbot/templates/config.yaml index 941b63ec..c153df82 100644 --- a/src/langbot/templates/config.yaml +++ b/src/langbot/templates/config.yaml @@ -89,6 +89,7 @@ monitoring: check_interval_hours: 1 box: profile: 'default' + image: '' # Custom sandbox container image. Leave empty to use the profile default (python:3.11-slim). runtime_url: '' # Action-RPC WebSocket URL of an external Box Runtime. Leave empty for auto-detection (stdio locally, Docker service in containers). shared_host_root: './data/box' # For Docker deployment, use '/workspaces' default_host_workspace: '' # Defaults to '/default'