feat: cloud adapters E2B/Modal and billing export (SAND-WP-0010)

Add credentialed E2B and Modal extensions, burst routing fallback,
fin-hub meter export hook, BYOK docs, and 77 tests.
This commit is contained in:
2026-06-24 12:50:19 +02:00
parent 6d0a1a8b1e
commit 15f031fd65
26 changed files with 859 additions and 75 deletions

View File

@@ -16,7 +16,12 @@ def _burst_profile() -> Profile:
"extension": "ext.compose-ssh",
"route": {
"strategy": "prefer-self-hosted",
"extensions": ["ext.compose-ssh", "ext.saas-stub"],
"extensions": [
"ext.compose-ssh",
"ext.e2b",
"ext.modal",
"ext.saas-stub",
],
},
}
)
@@ -42,12 +47,23 @@ def test_prefer_self_hosted_when_host_set(monkeypatch: pytest.MonkeyPatch) -> No
def test_prefer_self_hosted_falls_back_to_saas(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv("SANDBOXER_HOST", raising=False)
monkeypatch.delenv("E2B_API_KEY", raising=False)
monkeypatch.delenv("MODAL_TOKEN_ID", raising=False)
monkeypatch.setenv("SANDBOXER_FORCE_SAAS", "1")
ext = resolve_extension(_burst_profile(), {}, host_override=None)
assert ext.id == "ext.saas-stub"
assert ext.capabilities.pricing_model == "metered"
def test_prefer_self_hosted_falls_back_to_e2b_when_credentialed(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setenv("SANDBOXER_FORCE_SAAS", "1")
monkeypatch.setenv("E2B_API_KEY", "test-key")
ext = resolve_extension(_burst_profile(), {}, host_override=None)
assert ext.id == "ext.e2b"
def test_lowest_cost_picks_metered_when_forced(monkeypatch: pytest.MonkeyPatch) -> None:
profile = _burst_profile()
profile.route = RouteSpec(