Remote Agents (SSH)
Run long-lived “agent” processes on a VM/VPS over SSH and resume the flow later with structured results.
Quick Answer
Use a two-step pattern:
:sshkickoff step starts the remote agent/job quickly.:waitcallback step pauses the flow until the agent calls back.
This pattern is more robust than trying to keep a single SSH session open for hours.
If you still need to provision the machine, create the SSH connection, or wire the key material, start with Set Up A VPS Or VM For Breyta SSH.
Long-Running Job Guidance
For long-running or output-silent workloads, do not model the entire job as one sync :ssh
step. Workflow activity runtime limits can end a long sync SSH activity before the remote
process completes, even if the step :timeout is higher.
Authoritative guidance:
- Use sync
:sshfor short remote commands only. - For long or variable-duration jobs, use
:sshkickoff +:waitcallback. - Add a safety timeout callback path from the remote worker so runs resolve deterministically.
Pattern: Kickoff + Callback
1) Generate a correlation key
Use a deterministic key derived from the workflow id:
(let [ctx (:flow/ctx (flow/input))
workflow-id (:workflow-id ctx)
wait-key (str "agent-" workflow-id)]
...)
2) Compute a callback URL
The callback endpoint is:
POST /:workspace-id/events/<wait-key>
Example:
(let [base "https://<your-flows-api-host>/<workspace-id>"
callback-url (str base "/events/" wait-key)]
...)
Important:
- Your VM/VPS must be able to reach the callback URL.
- For local testing, use a tunnel (ngrok/cloudflared) or run flows-api on a reachable host.
3) Kick off the agent over SSH
Pass callback values to the remote process as environment variables:
(flow/step :ssh :kickoff
{:type :ssh
:title "Kick off remote agent"
:connection :vps
:command "nohup ./run-agent.sh >/tmp/agent.log 2>&1 & echo started"
:env {"BREYTA_WAIT_KEY" wait-key
"BREYTA_CALLBACK_URL" callback-url}
:timeout 60})
4) Wait for the callback
(flow/step :wait :await-callback
{:type :wait
:title "Wait for agent callback"
:key wait-key
:webhook {:auth {:type :none}} ; dev-friendly; use HMAC/signature in production
:timeout 3600
:on-timeout :fail})
5) Remote agent posts final output
The remote agent should POST JSON to BREYTA_CALLBACK_URL.
Example:
curl -X POST "$BREYTA_CALLBACK_URL" \
-H 'content-type: application/json' \
-d '{"status":"ok","result":{"answer":42}}'
The JSON payload becomes the :wait step result.
When To Use Sync SSH Instead
Use a single :ssh step (sync) when:
- the remote work is short-lived (seconds/minutes)
- you want the flow to wait naturally on the command exit status
See: Step SSH.
Should We Add An “Agent” Step?
Maybe later — but it’s usually best to start with the primitive (:ssh) and document the agent pattern.
What a dedicated :agent step could do (as a wrapper around :ssh + :wait):
- Standardize correlation (
wait-key) and callback URL generation. - Provide a canonical env contract (
BREYTA_WAIT_KEY,BREYTA_CALLBACK_URL, optional auth headers). - Offer a higher-level “kickoff + await result” interface with sensible defaults (timeouts, retries, max-output).
- Normalize the callback payload into a stable result shape (e.g.
{status, result, logsUrl, artifacts}). - Optionally stream progress via UI notifications (and/or accept progress callbacks).
Why start with :ssh first:
- It keeps the platform composable:
:sshworks for many non-agent tasks. - It avoids baking an “agent runtime” contract too early.
- You can still market “Remote Agent Kickoff” as a documented pattern and ship a
:agentstep once you see repeated configs in user flows.
VPS Provisioning (Options)
Bring your own VPS (BYO)
You provide:
- host/port/username
- SSH auth (private key or password via secret refs)
- host key verification (
known_hosts)
Pros:
- Works with any provider
- Maximum flexibility
Cons:
- More setup work (keys, host keys, firewalling)
Breyta-managed VPS per workspace (future direction)
In this model, Breyta would provision and manage a small VM per workspace and provide a standard “agent runtime”.
Potential benefits:
- Faster onboarding (“it just works”)
- Predictable runtime environment and paths
- Easier support and upgrades
Operational considerations:
- lifecycle + billing + quotas
- security posture, patching, auditing
- abuse prevention and network egress controls
- escape hatches (BYO VPS remains supported)
- secrets management UX (keys, host keys, callback auth) and rotation story