Sandboxes
Goal: add small application-level guardrails around tactic calls.
Prerequisites
python -m pip install -e ".[dev]"
Files Used
lllm/
sandbox.py
tests/
test_sandbox.py
Policy
from lllm import SandboxPolicy, SandboxedTactic
safe = SandboxedTactic(
tactic,
policy=SandboxPolicy(
timeout_seconds=2.0,
max_input_bytes=4096,
max_output_bytes=4096,
allowed_metadata_keys=("tenant", "trace"),
),
)
result = await safe.arun(
{"text": "hello"},
context=context,
)
SandboxedTactic wraps the public Tactic boundary, so it can sit around
plain Python, Pydantic AI, native, or remote tactics. It checks request metadata
before the call, input/output payload sizes around the call, and async/service
deadlines with asyncio.wait_for.
This is not OS-level isolation. Use containers, separate processes, or a real security sandbox for untrusted code. The LLLM sandbox wrapper is for reusable service guardrails and predictable error types.
Verify
python -m pytest tests/test_sandbox.py -q
Expected output:
... passed
Next, serve the sandboxed tactic so timeout and limit errors travel through the normal service error envelope.