Skip to content

feat(sdk): add ProcessBackend workflow for cloud sandbox execution#747

Merged
khaliqgant merged 7 commits into
mainfrom
feat/process-backend-runner
Apr 17, 2026
Merged

feat(sdk): add ProcessBackend workflow for cloud sandbox execution#747
khaliqgant merged 7 commits into
mainfrom
feat/process-backend-runner

Conversation

@khaliqgant
Copy link
Copy Markdown
Member

@khaliqgant khaliqgant commented Apr 16, 2026

Summary

Adds ProcessBackend and ProcessEnvironment interfaces to the SDK, accepts processBackend in WorkflowRunnerOptions, and creates a ProcessBackend-backed RunnerStepExecutor when no explicit executor is provided.

What changed

  • Exports ProcessBackend and ProcessEnvironment from @agent-relay/sdk/workflows
  • WorkflowRunnerOptions accepts an optional processBackend
  • Agent and deterministic workflow steps can execute through ProcessEnvironment.exec
  • env, cwd, and ceil-rounded timeoutSeconds are passed through structured exec options
  • RelayCast.createWorkspace() API-key handling now guards the optional apiKey shape from the latest @relaycast/sdk types

Boundary

Relay owns ProcessBackend provides
CLI command construction and args createEnvironment()
auth env, cwd, timeout metadata exec(command, opts)
workflow step lifecycle destroy()

uploadFile() remains part of the interface for future file asset staging and is not called by the current executor.

PR feedback addressed

  • Workflow commit step now checks out feat/process-backend-runner before committing and pushes that branch explicitly
  • Workflow task prompt no longer contains the old contradictory "stored but unused" guidance
  • Public comments/docs now describe the TS executor path accurately instead of implying broker-side remote spawning is already implemented
  • ProcessBackend executor keeps the previously resolved env and cwd behavior

Test plan

  • npm --prefix packages/sdk run build
  • npm run build:packages
  • npm run build
  • npx vitest run --config vitest.config.ts src/workflows/__tests__/process-backend-executor.test.ts from packages/sdk

Adds ProcessBackend + ProcessEnvironment interfaces to the SDK and
accepts processBackend in WorkflowRunnerOptions. Relay-side counterpart
to AgentWorkforce/cloud#115.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 787ef38a2a

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread workflows/wire-process-backend.ts Outdated
Comment on lines +402 to +403
command: 'git add packages/sdk/src/workflows/types.ts packages/sdk/src/workflows/runner.ts && git diff --cached --quiet && echo "NO CHANGES" && exit 1; git commit -m "feat(sdk): add ProcessBackend interface and accept in WorkflowRunnerOptions" && git push origin feat/process-backend-runner',
captureOutput: true,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Switch to feat branch before committing and pushing

In workflows/wire-process-backend.ts (checked the commit/open-pr steps), the script never creates or checks out feat/process-backend-runner before running git commit, but then pushes and opens a PR from that fixed branch name. When this workflow is run from another branch (e.g., main), the new commit is created on the current branch and either git push origin feat/process-backend-runner fails because the local ref does not exist, or it pushes an older unrelated local branch with that name, producing a PR without the new changes.

Useful? React with 👍 / 👎.

devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

@xkonjin xkonjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review — ProcessBackend wiring workflow

This is a workflow script that generates a PR, not a runtime change, so the risk surface is low. A few things worth tightening before it lands:

  1. Shell escaping in the workflow script — the generated uses a hand-rolled regex to decide when to quote args. That's fragile for args containing spaces, unicode, or pipes. Prefer or a proper shell-escape helper, or pass and as an array to if the backend supports it.

  2. Timeout math — can round a 500ms timeout up to 1s, which is fine, but document that the backend's is ceil-rounded from milliseconds.

  3. Missing usage — the task narrative mentions as part of the interface but the workflow executor never calls it. If agent steps need file assets (e.g. context bundles), consider where fits in .

  4. Broker still required? — the workflow itself disables the fork change (). Make sure the final PR description is crystal clear that is accepted but not yet wired into execution.

Nothing blocking, just polish.

Copy link
Copy Markdown

@xkonjin xkonjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review — ProcessBackend wiring workflow

This is a workflow script that generates a PR, not a runtime change, so the risk surface is low. A few things worth tightening before it lands:

  1. Shell escaping in the workflow script — the generated command uses a hand-rolled regex /^[a-zA-Z0-9._\\-\\/=]+$/ to decide when to quote args. That's fragile for args containing spaces, unicode, or pipes. Prefer JSON.stringify(arg).slice(1, -1) or a proper shell-escape helper, or pass cmd and args as an array to env.exec if the backend supports it.

  2. Timeout mathMath.max(1, Math.ceil(timeoutMs / 1000)) can round a 500ms timeout up to 1s, which is fine, but document that the backend's timeoutSeconds is ceil-rounded from milliseconds.

  3. Missing uploadFile usage — the task narrative mentions uploadFile as part of the interface but the workflow executor never calls it. If agent steps need file assets (e.g. context bundles), consider where uploadFile fits in executeAgentStep.

  4. Broker still required? — the workflow itself disables the fork change (DO NOT change the fork at line 4038). Make sure the final PR description is crystal clear that processBackend is accepted but not yet wired into execution.

Nothing blocking, just polish.

devin-ai-integration[bot]

This comment was marked as resolved.

kjgbot and others added 3 commits April 16, 2026 19:53
…ts pass

The fix-failures agent step always spawned Claude even when build+tests
passed, causing 3 timeout retries. Now build/test steps use failOnError:true
and gate commit directly. Also makes open-pr idempotent (skips if PR exists).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The runner now synthesizes a RunnerStepExecutor from processBackend
when no explicit executor is supplied, so every existing
executor.executeAgentStep() call site flows through
processBackend.createEnvironment().exec() without further plumbing.

Adds:
- process-backend-executor.ts adapter (buildCommand → env.exec, with
  cwd/env/timeout propagation and env.destroy() in finally)
- unit tests covering the happy path, non-zero exit, cli:"api" rejection,
  and deterministic-step pass-through
- index export for createProcessBackendExecutor

Replaces the "stored but unused" TODO in runner.ts:4052 with a pointer
to the adapter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

Addresses PR #747 feedback:

- executeAgentStep was baking env vars into the command as a shell
  prefix and never forwarding agentDef.cwd. Structured backends
  (process-backend implementations that configure subprocess env/cwd
  from execOpts) would therefore miss auth env and run commands in
  the wrong directory. Drop the shell-prefix path and pass both env
  and cwd through execOpts, matching executeDeterministicStep.

- Test mocks were declared with vi.fn(async () => ...) which infers
  an empty-tuple call signature, so exec.mock.calls[0] typed as [].
  Fix by typing mocks as vi.fn<ProcessEnvironment['exec']>(...).
  This resolves every CI failure on the PR (SDK typecheck, SDK
  build, Test, E2E, Package Validation, Clean-Room, Workers Safety,
  Workflow Validation) — all cascaded from the same TS2493/TS2339.

- Add a test that asserts env is *not* baked into the command and
  that agentDef.cwd flows through execOpts.
@khaliqgant khaliqgant merged commit 9f74bbc into main Apr 17, 2026
41 checks passed
@khaliqgant khaliqgant deleted the feat/process-backend-runner branch April 17, 2026 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants