Skip to content

Commit 585afbd

Browse files
feat(box): add session workspace quota enforcement and SDK quota metadata
1 parent 4bdc2c4 commit 585afbd

4 files changed

Lines changed: 18 additions & 3 deletions

File tree

src/langbot_plugin/box/backend.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ async def start_session(self, spec: BoxSpec) -> BoxSessionInfo:
130130
f'image={spec.image} network={spec.network.value} '
131131
f'host_path={spec.host_path} host_path_mode={spec.host_path_mode.value} mount_path={spec.mount_path} '
132132
f'cpus={spec.cpus} memory_mb={spec.memory_mb} pids_limit={spec.pids_limit} '
133-
f'read_only_rootfs={spec.read_only_rootfs}'
133+
f'read_only_rootfs={spec.read_only_rootfs} workspace_quota_mb={spec.workspace_quota_mb}'
134134
)
135135

136136
await self._run_command(args, timeout_sec=30, check=True)
@@ -148,6 +148,7 @@ async def start_session(self, spec: BoxSpec) -> BoxSessionInfo:
148148
memory_mb=spec.memory_mb,
149149
pids_limit=spec.pids_limit,
150150
read_only_rootfs=spec.read_only_rootfs,
151+
workspace_quota_mb=spec.workspace_quota_mb,
151152
created_at=now,
152153
last_used_at=now,
153154
)

src/langbot_plugin/box/models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class BoxSpec(pydantic.BaseModel):
4747
memory_mb: int = 512
4848
pids_limit: int = 128
4949
read_only_rootfs: bool = True
50+
workspace_quota_mb: int = 0
5051

5152
@pydantic.model_validator(mode='before')
5253
@classmethod
@@ -102,6 +103,13 @@ def validate_pids_limit(cls, value: int) -> int:
102103
raise ValueError('pids_limit must be at least 1')
103104
return value
104105

106+
@pydantic.field_validator('workspace_quota_mb')
107+
@classmethod
108+
def validate_workspace_quota_mb(cls, value: int) -> int:
109+
if value < 0:
110+
raise ValueError('workspace_quota_mb must be greater than or equal to 0')
111+
return value
112+
105113
@pydantic.field_validator('session_id')
106114
@classmethod
107115
def validate_session_id(cls, value: str) -> str:
@@ -162,6 +170,7 @@ class BoxProfile(pydantic.BaseModel):
162170
memory_mb: int = 512
163171
pids_limit: int = 128
164172
read_only_rootfs: bool = True
173+
workspace_quota_mb: int = 0
165174
locked: frozenset[str] = frozenset()
166175

167176
model_config = pydantic.ConfigDict(frozen=True)
@@ -225,6 +234,7 @@ class BoxSessionInfo(pydantic.BaseModel):
225234
memory_mb: int = 512
226235
pids_limit: int = 128
227236
read_only_rootfs: bool = True
237+
workspace_quota_mb: int = 0
228238
created_at: dt.datetime
229239
last_used_at: dt.datetime
230240

src/langbot_plugin/box/nsjail_backend.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ async def start_session(self, spec: BoxSpec) -> BoxSessionInfo:
136136
f'session_id={spec.session_id} session_dir={session_dir} '
137137
f'network={spec.network.value} '
138138
f'host_path={spec.host_path} host_path_mode={spec.host_path_mode.value} mount_path={spec.mount_path} '
139-
f'cpus={spec.cpus} memory_mb={spec.memory_mb} pids_limit={spec.pids_limit}'
139+
f'cpus={spec.cpus} memory_mb={spec.memory_mb} pids_limit={spec.pids_limit} '
140+
f'workspace_quota_mb={spec.workspace_quota_mb}'
140141
)
141142

142143
return BoxSessionInfo(
@@ -152,6 +153,7 @@ async def start_session(self, spec: BoxSpec) -> BoxSessionInfo:
152153
memory_mb=spec.memory_mb,
153154
pids_limit=spec.pids_limit,
154155
read_only_rootfs=spec.read_only_rootfs,
156+
workspace_quota_mb=spec.workspace_quota_mb,
155157
created_at=now,
156158
last_used_at=now,
157159
)

src/langbot_plugin/box/runtime.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ async def _get_or_create_session(self, spec: BoxSpec) -> _RuntimeSession:
220220
f'network={info.network.value} '
221221
f'host_path={info.host_path} '
222222
f'host_path_mode={info.host_path_mode.value} '
223-
f'mount_path={info.mount_path}'
223+
f'mount_path={info.mount_path} '
224+
f'workspace_quota_mb={info.workspace_quota_mb}'
224225
)
225226
return runtime_session
226227

@@ -290,6 +291,7 @@ def _assert_session_compatible(self, session: BoxSessionInfo, spec: BoxSpec):
290291
'memory_mb',
291292
'pids_limit',
292293
'read_only_rootfs',
294+
'workspace_quota_mb',
293295
)
294296
for field in _COMPAT_FIELDS:
295297
session_val = getattr(session, field)

0 commit comments

Comments
 (0)