Skip to Content
ProvidersRuntime

Runtime

Runtime providers manage where executable plugins and hosted agent providers run.

A runtime provider is not the plugin itself, and it is not a host provider like authentication, IndexedDB, or workflow. Instead, it is a control-plane backend that lets gestaltd create a plugin runtime session, bind host-local services into that session, start the plugin process there, and dial the plugin back over gRPC.

Scope

Runtime providers apply to executable plugins under plugins.<name> and agent providers under providers.agent.<name> when they opt into hosted execution. They do not replace host-local infrastructure providers such as authentication, authorization, IndexedDB, cache, S3, secrets, or workflow. Those providers still live on the gestaltd host. A runtime provider only changes where the configured plugin or agent provider process runs.

Mental model

By default, executable plugins and agent providers run on the same machine as gestaltd. A provider only uses a runtime provider when it opts in with execution.mode: hosted. Use execution.mode: hosted with execution.runtime; legacy plugins.<name>.runtime and providers.agent.<name>.runtime fields are no longer accepted.

When a provider does opt in, Gestalt selects a backend from runtime.providers, reads the backend’s support profile, starts a runtime session, waits for that session to become ready, binds any required host-local services, starts the provider process inside the session, then dials it back over gRPC. From that point on, the hosted provider behaves like any other configured provider from the caller’s point of view. Gestalt stops the runtime session during shutdown or after a bootstrap failure.

That is why the runtime interface is bigger than a single StartPlugin call: Gestalt needs an explicit lifecycle boundary, not just a fire-and-forget launch RPC.

Configuring a runtime provider

Runtime providers are configured under top-level runtime.providers:

runtime: providers: modal: source: path: ./vendor/gestalt-providers/runtime/modal/manifest.yaml default: true config: app: gestalt-runtime environment: main server: runtime: defaultHostedProvider: modal plugins: support: source: ./plugins/support/manifest.yaml execution: mode: hosted runtime: image: ghcr.io/example/support-plugin:2026-04-21 template: python-dev metadata: environment: production

Selection is intentionally two-step. runtime.providers defines named backends, while execution.mode: hosted opts a specific plugin or agent provider into hosted execution. server.runtime.defaultHostedProvider is only a default selector for providers that already opted into hosted execution.

Runtime profiles

Runtime backends are not interchangeable, but the compatibility check is meant to read in terms of behavior, not implementation details. Gestalt asks whether the runtime can host plugins, how hosted plugins reach Gestalt-owned services, and whether the runtime can preserve hostname-based egress.allowedHosts.

Host-service access is reported as none, relay, or direct. direct means the runtime can expose guest-local service sockets inside the session. relay means the current host deployment can provide those services through Gestalt’s public relay path. Egress support is separate: a runtime must preserve Gestalt’s hostname-based policy model before plugins with egress.allowedHosts or a default-deny egress policy can run there.

The admin inspection API exposes both sides of that decision. GET /admin/api/v1/runtime/providers includes profile.advertised, which is what the runtime reports, and profile.effective, which is what this gestaltd deployment can actually provide after relay and public proxy prerequisites are considered.

Host services and hosted plugins

Plugins do not talk directly to host-local services over the public network. gestaltd starts those services on the host and then gives the runtime one of two integration paths. A runtime with direct host-service access can bind guest-local sockets straight into the session. A runtime without that direct path can still use relay-backed bindings, in which case the hosted plugin talks back to gestaltd over a scoped public relay target and gestaltd forwards the request to the real host-local service.

That same split shows up in hostname-based egress. A runtime may preserve egress.allowedHosts internally, or it may preserve it by routing hosted HTTP(S) traffic through Gestalt’s public egress proxy. Either way, the contract is that the meaning of egress.allowedHosts stays the same from the plugin’s point of view.

The runtime provider is also responsible for the plugin’s own listener endpoint. StartPlugin must start the plugin, allocate or inject its provider listener, and return a host-reachable dial_target. Gestalt currently supports unix://, tcp://, and tls:// dial targets.

Local vs hosted backends

Today there are two main runtime choices:

BackendTypeNotes
localBuilt-in driverRuns the plugin on the same machine as gestaltd. Supports host-path execution and the existing host-local runtime behavior.
modalInstallable kind: runtime providerRuns the plugin in a hosted Linux sandbox. Requires runtime.providers.<name>.config.app and plugins.<name>.execution.runtime.image. When the host is configured for the public relay and proxy path, Modal can run plugins that need Gestalt-owned services and hostname-based egress.

Provider images

Hosted runtime providers run prebuilt provider images. Gestalt does not upload provider bundles into those sessions. Instead, the configured image must contain the provider package at the image working directory and preserve the release package layout. Gestalt starts the manifest entrypoint path from that working directory and passes the manifest entrypoint args.

plugins: support: source: https://artifacts.example.com/support/v0.1.0/provider-release.yaml execution: mode: hosted runtime: provider: modal image: ghcr.io/example/support-plugin@sha256:...

This is why plugins.<name>.execution.runtime.image, template, imagePullAuth, and metadata are forwarded to the runtime backend: they are runtime-specific session hints, not universal plugin semantics. For private OCI images, imagePullAuth.dockerConfigJson carries Docker config JSON, matching the registry auth material used by Docker and Kubernetes image pull secrets. Keep the manifest release and image digest in sync; Gestalt does not inspect the image to prove that the manifest entrypoint exists inside it.

For the config fields, see Configuration and Config File. For plugin-side opt-in, see Plugin. For the execution boundary, see Security. To build a runtime backend, see Custom Providers > Runtime.