Agent Runtime Backend Initialization#
The dify-agent FastAPI server initializes its sandbox runtime at startup through a two-stage process: ServerSettings resolves DIFY_AGENT_* environment variables into a RuntimeBackendProfile, and create_default_layer_providers() wires that profile into the LayerProvider set consumed by the RunScheduler. Layers and providers never read environment variables directly β all credentials and endpoints are injected at construction time.
Initialization Flow#
create_app() in server/app.py orchestrates the startup sequence:
ServerSettingsis instantiated, loading allDIFY_AGENT_*env vars via Pydantic Settings.settings.build_runtime_backend_profile()callscreate_runtime_backend_profile(RuntimeBackendSettings(...)). For thelocalbackend, it returnsNonewhenDIFY_AGENT_LOCAL_SANDBOX_ENDPOINTis not set ; for all other backends, missing required credentials raiseValueErrorat startup before any traffic is accepted .create_default_layer_providers()receives the profile (orNone) plus plugin-daemon and inner-API credentials, and builds a tuple ofLayerProviderobjects.- The resulting providers tuple is passed to
RunSchedulerduring the FastAPI lifespan, servicing all run requests in-process.
ServerSettings (DIFY_AGENT_* env vars)
ββ build_runtime_backend_profile()
ββ create_runtime_backend_profile(RuntimeBackendSettings)
ββ RuntimeBackendProfile { execution_bindings, home_snapshots }
create_default_layer_providers(runtime_backend_profile=...)
ββ always: DifyShellLayer, DifyExecutionContextLayer, PromptLayer, ...
ββ optional: DifyRuntimeLayer (only when profile is not None)
β
RunScheduler (lifespan-scoped)
Backend Selection#
DIFY_AGENT_RUNTIME_BACKEND (default: local) selects one of four backends . create_runtime_backend_profile() constructs the matching execution_bindings + home_snapshots driver pair:
| Backend | Required env var(s) | execution_bindings type |
|---|---|---|
local | DIFY_AGENT_LOCAL_SANDBOX_ENDPOINT (or legacy DIFY_AGENT_SHELLCTL_ENTRYPOINT) | LocalExecutionBindingBackend |
enterprise | DIFY_AGENT_ENTERPRISE_SANDBOX_GATEWAY_ENDPOINT | EnterpriseExecutionBindingBackend |
e2b | DIFY_AGENT_E2B_API_KEY | E2BExecutionBindingBackend |
openshell | DIFY_AGENT_OPENSHELL_GATEWAY_ENDPOINT, DIFY_AGENT_OPENSHELL_DRIVER_CONFIG, DIFY_AGENT_OPENSHELL_SHELLCTL_AUTH_TOKEN | OpenShellExecutionBindingBackend |
- Local: connects to a shellctl sandbox via
DIFY_AGENT_LOCAL_SANDBOX_ENDPOINT. Home dirs are materialized underDIFY_AGENT_LOCAL_SANDBOX_MATERIALIZED_HOME_ROOT(default/home/dify) and snapshots underDIFY_AGENT_LOCAL_SANDBOX_HOME_SNAPSHOT_ROOT(default/home/dify/.snapshots) . - Enterprise: uses a gateway at
DIFY_AGENT_ENTERPRISE_SANDBOX_GATEWAY_ENDPOINTwith configurable control-plane/proxy timeout separation . - E2B: uses the E2B SDK keyed by
DIFY_AGENT_E2B_API_KEY, with a configurable sandbox template (defaultdifys-default-team/dify-agent-local-sandbox) and active timeout . - OpenShell: manages sandboxes on a self-hosted NVIDIA OpenShell gateway via gRPC. The backend bootstraps shellctl via an idempotent control exec on acquire and reaches it through authenticated
ForwardTcptunnels. Home snapshots are directory copies on a shared volume (no native snapshot capability). RequiresDIFY_AGENT_OPENSHELL_DRIVER_CONFIG(JSON object mounting the shared Home Snapshot volume) .
Layer Provider Registration#
create_default_layer_providers() always registers the following providers :
- Direct type (
LayerProvider.from_layer_type()):PromptLayer,DifyUserPromptLayer,PydanticAIHistoryLayer,DifyOutputLayer,DifyAskHumanLayer,DifyConfigLayer - Factory-wrapped (
LayerProvider.from_factory()):DifyExecutionContextLayer,DifyShellLayer,DifyPluginLLMLayer,DifyPluginToolsLayer,DifyCoreToolsLayer,DifyKnowledgeBaseLayer
DifyRuntimeLayer is conditionally appended only when runtime_backend_profile is not None . If absent, any run that requires dify.runtime or dify.shell fails at run time (not at startup).
Shell Layer: Enforced Factory Pattern#
DifyShellLayer.from_config() raises TypeError β direct construction is blocked. The factory always calls from_config_with_settings(), which injects three server-owned values absent from per-run HTTP payloads:
shell_redact_patternsβ server-level regex list for masking secrets in shell outputagent_stub_api_base_urlβ public Agent Stub endpoint URLagent_stub_token_factoryβ callable that mints JWE tokens for shell jobs
The same pattern applies to DifyRuntimeLayer: from_config() raises TypeError; the only valid path is from_config_with_backend(), which accepts the ExecutionBindingBackend from the RuntimeBackendProfile .
DifyShellLayer does not own the sandbox connection. Every shell tool call reads the RuntimeLease via _require_resource() from its DifyRuntimeLayer dependency. HOME is set from lease.layout.home_dir, which is controlled exclusively by the runtime backend .
Key Settings Reference#
All settings live in ServerSettings under the DIFY_AGENT_ env-var prefix:
| Setting | Default | Purpose |
|---|---|---|
DIFY_AGENT_RUNTIME_BACKEND | local | Backend selector |
DIFY_AGENT_LOCAL_SANDBOX_ENDPOINT | None | Shellctl server URL (local backend) |
DIFY_AGENT_ENTERPRISE_SANDBOX_GATEWAY_ENDPOINT | None | Gateway URL (enterprise backend) |
DIFY_AGENT_E2B_API_KEY | None | API key (e2b backend) |
DIFY_AGENT_SHELL_REDACT_PATTERNS | "" | JSON array of regex patterns for output redaction |
DIFY_AGENT_STUB_API_BASE_URL | None | Agent Stub endpoint (required for JWE token issuance) |
DIFY_AGENT_SERVER_SECRET_KEY | None | 32-byte base64url key; required when Stub URL is set |
DIFY_AGENT_SANDBOX_FILES_BASE_URL | None | Base URL reachable from sandbox container for file transfers |
DIFY_AGENT_INNER_API_URL | http://127.0.0.1:5001 | Host-side Dify API URL for control-plane calls |
Key Entry Points#
| File | Purpose |
|---|---|
server/app.py | create_app() β top-level startup wiring |
server/settings.py | ServerSettings, build_runtime_backend_profile() |
runtime/compositor_factory.py | create_default_layer_providers() β provider set assembly |
runtime_backend/profile.py | RuntimeBackendSettings, create_runtime_backend_profile() |
layers/shell/layer.py | DifyShellLayer β enforced from_config_with_settings() factory |