feat(exec): add cloud execution provider (host="cloud")#41308
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ae3e9b04f4
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
ae3e9b0 to
cdf6265
Compare
Greptile SummaryThis PR introduces Key finding:
Confidence Score: 3/5
Last reviewed commit: cdf6265 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cdf6265468
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
cdf6265 to
61fee51
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 61fee511ad
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
61fee51 to
74cf886
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 74cf88652b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
f026463 to
263d552
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 263d552e60
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| await scopedSession.onKill(); | ||
| } catch { | ||
| // best-effort; fall through to markExited below | ||
| } | ||
| markExited(scopedSession, null, "SIGKILL", "killed"); |
There was a problem hiding this comment.
Fail cloud kill requests when provider termination errors
If scopedSession.onKill() throws (for example, network/API failure while terminating a cloud session), the error is swallowed and the code still calls markExited(..., "killed"). That reports the session as killed and removes it from active tracking even though the remote process may still be running, so users cannot retry process kill and may leak cloud compute jobs.
Useful? React with 👍 / 👎.
| if (params.backgroundMs !== undefined || params.yieldMs !== undefined) { | ||
| const cloudSession = await provider.execBackground({ | ||
| command: params.command, | ||
| cwd: params.workdir, | ||
| env: params.env, | ||
| }); |
There was a problem hiding this comment.
Apply exec timeout to cloud background sessions
The background branch starts provider.execBackground(...) without any timeout or watchdog, even though timeoutMs is computed earlier from timeoutSec/defaultTimeoutSec. This means exec calls with host="cloud" and background/yieldMs ignore explicit time limits and can run indefinitely, unlike the non-cloud path where explicit timeouts still bound backgrounded runs.
Useful? React with 👍 / 👎.
| // Track how many bytes we've already appended so we only forward the | ||
| // incremental portion — readSessionLog() returns *accumulated* output. | ||
| let appendedLength = 0; | ||
| // eslint-disable-next-line no-constant-condition |
There was a problem hiding this comment.
Initialize cloud log offset from initial output
The proxy session is pre-seeded with cloudSession.initialOutput, but polling starts with appendedLength = 0. Since readSessionLog() returns accumulated output, the first poll re-appends the initial bytes that are already in aggregated, duplicating output and inflating truncation counters for every background session that returns startup output.
Useful? React with 👍 / 👎.
263d552 to
358baf9
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 358baf9aa8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
358baf9 to
39dc44b
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 39dc44bf58
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
39dc44b to
2aacbdf
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2aacbdfe06
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
2aacbdf to
6fd7df7
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6fd7df724d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
6fd7df7 to
91d904f
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 91d904f6ec
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| await provider.ensureReady(); | ||
|
|
||
| const warningText = params.warnings.length ? `${params.warnings.join("\n")}\n\n` : ""; | ||
| const timeoutMs = (params.timeoutSec ?? params.defaultTimeoutSec) * 1000; |
There was a problem hiding this comment.
Preserve background no-timeout semantics for cloud host
When host="cloud" and the command is yielded/backgrounded without an explicit timeout, this code still derives timeoutMs from defaultTimeoutSec and the polling watchdog later enforces it, so long-running jobs are force-killed after the default window (30m) instead of running until completion. The non-cloud path intentionally bypasses default timeouts for background/yielded runs (effectiveTimeout = null), so this introduces host-specific behavior that can terminate valid cloud background tasks unexpectedly.
Useful? React with 👍 / 👎.
| proxySession, | ||
| log.exitCode ?? null, | ||
| null, | ||
| log.exitCode === 0 ? "completed" : "failed", |
There was a problem hiding this comment.
Handle completed cloud logs without exit code
CloudExecSessionLog.exitCode is optional in the provider contract, but completion is classified with log.exitCode === 0 ? "completed" : "failed". If a provider reports done: true without exitCode (which the type allows), the session is always marked failed even for successful commands, causing incorrect process status/results for compliant providers.
Useful? React with 👍 / 👎.
91d904f to
a78cddb
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a78cddb17b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| command: params.command, | ||
| scopeKey: params.scopeKey, | ||
| sessionKey: params.sessionKey, | ||
| notifyOnExit: false, |
There was a problem hiding this comment.
Honor notify-on-exit for cloud background sessions
This branch hard-codes notifyOnExit: false for cloud proxy sessions, so backgrounded host="cloud" commands never emit completion notifications even when exec defaults enable notify-on-exit. In practice, users who rely on automatic completion follow-ups (instead of manual process poll) lose that behavior only on cloud runs, which makes cloud execution inconsistent with the rest of the exec tool contract.
Useful? React with 👍 / 👎.
| maxOutputChars: 200_000, | ||
| pendingMaxOutputChars: 30_000, |
There was a problem hiding this comment.
Use configured output caps for cloud proxy sessions
The cloud proxy session uses fixed maxOutputChars/pendingMaxOutputChars values (200_000/30_000) instead of the runtime-configured limits used by other exec hosts. If operators lower PI_BASH_MAX_OUTPUT_CHARS or OPENCLAW_BASH_PENDING_MAX_OUTPUT_CHARS to control memory/truncation behavior, cloud sessions ignore those settings and can retain far more output than intended.
Useful? React with 👍 / 👎.
a78cddb to
da25f98
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: da25f982cf
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| return executeCloudHostCommand({ | ||
| command: params.command, | ||
| workdir, | ||
| env, |
There was a problem hiding this comment.
Do not forward inherited host env into cloud exec
This cloud branch passes env built from sanitizeHostBaseEnv(process.env) to executeCloudHostCommand, and that handler forwards it directly to provider.exec/execBackground, so host="cloud" commands inherit gateway process secrets (API keys/tokens) by default; a simple remote env command can expose them in tool output. The node-host path avoids this by only forwarding request-scoped overrides (requestedEnv), so cloud should not receive the full inherited base environment.
Useful? React with 👍 / 👎.
|
This pull request has been automatically marked as stale due to inactivity. |
|
Closing this as implemented after Codex automated review. Current main implements the central cloud/remote exec problem through the shipped pluggable sandbox backend API, plus SSH and OpenShell backends, rather than adding a parallel Best possible solution: Close this PR and keep the shipped sandbox-backend architecture as the product path: cloud/remote exec providers should implement What I checked:
So I’m closing this as already implemented rather than keeping a duplicate issue open. Codex Review notes: model gpt-5.5, reasoning high; reviewed against 5828dcdb05aa; fix evidence: release 2026.3.22, commit 5828dcdb05aa. |
Summary
Add
"cloud"as a newExecHostvariant forexecandbrowsertools, enabling transparent command routing to cloud sandbox runtimes provided by plugins (Firecracker MicroVMs, E2B, Modal, etc.) without requiring a local Docker container.CloudSandboxProvider interface:
exec,execBackground,readSessionLog,killSessiongetBrowserCdpUrl()/getBrowserVncUrl()for CDP-based browser automationensureReady()(lazy init),dispose()(cleanup),isReady()(health check)registerService("cloud-sandbox:<id>", ...))Cloud sandbox registry:
resolveCloudSandboxProvider(providerId?)— looks up the plugin service registry for registered cloud-sandbox servicesproviderIdCloud exec handler:
bash-tools.exec-host-node.tsprovider.exec()→ formatted stdout/stderr/exitCode resultprovider.execBackground()→ session handle with initial outputresolveExecHostApprovalContext)emitExecSystemEventfor heartbeat coordinationExec routing integration:
host="cloud"branch inserted inbash-tools.exec.tsbefore thehost="node"path"allowlist"(same ashost="gateway") via existing logic — no special-casing neededBrowser tool cloud target:
target="cloud"resolvesCloudSandboxProvider.getBrowserCdpUrl()and passes CDP URL toBrowserBridgeType/schema extensions (6 files):
ExecHosttype, config type, zod schema, normalizers, and error messages all updated to include"cloud"Also includes:
pathPrependwarning extended to coverhost="cloud"(not supported on cloud hosts)Design decisions
host="cloud"should NOT default tosecurity="full". The implementation follows this — cloud inherits"allowlist"through the existing default atbash-tools.exec.ts:321.executeCloudHostCommandaccepts aproviderparameter for testability, defaulting toresolveCloudSandboxProvider().target="cloud". Auto-detection deferred to follow-up.openclaw doctordeferred to follow-up PR.Changes
src/infra/exec-approvals.ts— add"cloud"toExecHostunionsrc/config/types.tools.ts— add"cloud"to config host typesrc/config/zod-schema.agent-runtime.ts— add"cloud"to zod enumsrc/agents/bash-tools.exec-runtime.ts— updatenormalizeExecHost()andrenderExecHostLabel()src/gateway/sessions-patch.ts— update local normalizer + error messagesrc/auto-reply/reply/exec/directive.ts— update local normalizersrc/infra/cloud-sandbox-provider.ts— new:CloudSandboxProviderinterface + param/result typessrc/infra/cloud-sandbox-registry.ts— new: plugin registry lookup for cloud providerssrc/agents/bash-tools.exec-host-shared.ts— expand host param to include"cloud"src/agents/bash-tools.exec-host-cloud.ts— new: cloud exec handler (sync + background)src/agents/bash-tools.exec.ts— add cloud routing branch + pathPrepend warningsrc/agents/tools/browser-tool.schema.ts— add"cloud"toBROWSER_TARGETSsrc/agents/tools/browser-tool.ts— add cloud CDP target resolutionsrc/infra/cloud-sandbox-registry.test.ts— new: 6 testssrc/agents/bash-tools.exec-host-cloud.test.ts— new: 12 testssrc/agents/bash-tools.exec-runtime.test.ts— add cloud normalizer + label testsExample config
When no cloud sandbox plugin is installed, this produces a clear error:
Test plan
tsc --noEmit— 0 type errorspnpm lint(oxlint --type-aware) — 0 warnings, 0 errors on 4728 filespnpm format(oxfmt) — cleanpnpm test -- --run src/infra/cloud-sandbox-registry.test.ts src/agents/bash-tools.exec-host-cloud.test.ts src/agents/bash-tools.exec-runtime.test.ts— 28/28 passpnpm test— full suite passes (sole pre-existing failure inbootstrap-extra-files/handler.test.ts, unrelated)tools.exec.host: "cloud"without a plugin → verify error message