Architecture: How to decouple ComputerUseLoopService from E2BDesktopServic...
Documentation for Sessions
ποΈ Architecture: How to decouple ComputerUseLoopService from E2BDesktopServic...
Date: 2026-02-26
Time: 16:53:19 UTC
Session: gspace1-144.6
Agent: backend
Confidence: 95%
Status: β
Documented
π Decision Context
Question:
How to decouple ComputerUseLoopService from E2BDesktopService to support multiple sandbox backends (E2B Cloud, Self-Hosted Firecracker, Playwright)?
Task: Implement self-hosted E2B provider abstraction (Gap 10)
π― Decision Made
Chosen:
Strategy pattern with SandboxProvider interface, SandboxProviderFactory (env-based selection at OnModuleInit), and 3 concrete providers: E2BCloudProvider (wraps existing service), SelfHostedProvider (HTTP to orchestrator), PlaywrightProvider (wraps BrowserAutomationService)
Options Considered:
- Adapter pattern wrapping each provider individually β rejected: doesn't solve runtime selection
- Dependency injection with conditional module imports via useFactory β rejected: NestJS doesn't support conditional provider registration cleanly at runtime
- Strategy pattern with factory selecting provider at module init β chosen: clean separation, env-var driven, testable, backward compatible
π Reasoning
ROOT CAUSE: ComputerUseLoopService had 15+ direct calls to this.e2bDesktop.* methods (screenshot, click, type, scroll, etc.). Adding a second provider would require if/else branching throughout the entire observe-think-act loop. SOLUTION: Strategy pattern with SandboxProvider interface defining 15 methods matching the existing E2BDesktopService API surface. SandboxProviderFactory.onModuleInit() checks env vars in priority order: SANDBOX_SERVER_URL β self-hosted (production Firecracker VMs), E2B_API_KEY β E2B cloud (existing behavior), else β Playwright fallback. E2BCloudProvider wraps E2BDesktopService 1:1, maintaining backward compatibility. SandboxHandle abstracts the sandbox identity (sandboxId, sessionId, userId, timestamps) replacing the raw any type. WHAT WOULD MAKE THIS WRONG: If providers need fundamentally different interaction models (e.g., async screenshot vs sync, or batch actions). Currently all 3 share the same synchronous actionβresult model. EARLY WARNING: If a new provider needs capabilities not in SandboxProvider interface (e.g., GPU access, audio), the interface needs extension. Monitor for methods that return empty strings or no-ops in PlaywrightProvider β these indicate capability gaps.
π Files Involved
APIs/backend-ai-api/src/app/infrastructure/services/sandbox/sandbox-provider.interface.tsAPIs/backend-ai-api/src/app/infrastructure/services/sandbox/sandbox-provider.factory.tsAPIs/backend-ai-api/src/app/infrastructure/services/sandbox/e2b-cloud.provider.tsAPIs/backend-ai-api/src/app/infrastructure/services/sandbox/self-hosted.provider.tsAPIs/backend-ai-api/src/app/infrastructure/services/sandbox/playwright.provider.tsAPIs/backend-ai-api/src/app/infrastructure/services/sandbox/index.tsAPIs/backend-ai-api/src/app/infrastructure/services/computer-use-loop.service.tsAPIs/backend-ai-api/src/app/infrastructure/infrastructure.module.ts
π Related
- Decision ID:
dev_1772124799695_xw9krx5 - Session: 144
- Workspace: gspace1
Auto-generated by MCP Smart Consolidation