Summary
Add a built-in replicate provider that can run Crabbox commands through a Replicate prediction or deployment backed by a compatible Crabbox runner model.
Replicate is not an SSH host or a general-purpose VM lease API. Its public control plane is centered on predictions, deployments, model versions, logs, output files, cancellation, and optional streaming. Because of that, the provider should be implemented as ProviderKindDelegatedRun, not ProviderKindSSHLease, and should be explicit that it requires a Replicate model or deployment whose input and output schema implements Crabbox's runner contract.
Motivation
Crabbox already supports providers that do not expose SSH by using delegated run backends, for example Modal, Freestyle, OpenComputer, CodeSandbox, and Upstash Box. Replicate can fit the same provider family if Crabbox treats Replicate prediction IDs as run/session handles and delegates workspace upload, command execution, log polling, cancellation, and output mapping to a runner model.
This would let users run:
REPLICATE_API_TOKEN=... crabbox run --provider replicate -- npm test
or configure a specific deployment:
provider: replicate
replicate:
deployment: example-org/crabbox-runner
workdir: /workspace/crabbox
waitSecs: 60
execTimeoutSecs: 3600
Replicate API facts
Relevant API and platform details from the Replicate documentation:
- Authentication uses
Authorization: Bearer $REPLICATE_API_TOKEN.
- Predictions can be created with
POST https://api.replicate.com/v1/predictions.
- Predictions can be fetched with
GET https://api.replicate.com/v1/predictions/{prediction_id}.
- Predictions can be listed with
GET https://api.replicate.com/v1/predictions.
- Predictions can be canceled with
POST https://api.replicate.com/v1/predictions/{prediction_id}/cancel.
- Deployment-backed predictions can be created with
POST https://api.replicate.com/v1/deployments/{deployment_owner}/{deployment_name}/predictions.
- Replicate supports
Prefer: wait for initial synchronous waiting.
- Prediction statuses include non-terminal and terminal lifecycle states such as starting, processing, succeeded, failed, and canceled.
- File inputs should be HTTP URLs or data URLs.
- Output files are represented as HTTPS URLs and may require the same
Authorization header to fetch.
- Deployments provide stable endpoints and hardware/scaling control, but billed runtime includes setup, idle, active, failed, and canceled deployment instance time as documented by Replicate.
Proposed provider shape
Provider metadata
Use canonical provider name replicate with no aliases initially.
Recommended ProviderSpec:
core.ProviderSpec{
Name: "replicate",
Family: "replicate",
Kind: core.ProviderKindDelegatedRun,
Targets: []core.TargetSpec{{OS: core.TargetLinux}},
Features: core.FeatureSet{core.FeatureArchiveSync, core.FeatureRunSession},
Coordinator: core.CoordinatorNever,
}
Do not advertise SSH, desktop, browser, code-server, Crabbox-owned sync, cleanup, pause/resume, run artifacts, or run downloads until those contracts are implemented and tested.
Runner contract requirement
The first implementation should document and enforce that replicate requires either:
- A configured Replicate deployment, for example
owner/name, that runs a Crabbox runner model, or
- A configured model version, only if direct version predictions can satisfy the same runner schema.
Suggested runner input schema:
{
"archive": "https://... or data:application/gzip;base64,...",
"command": ["npm", "test"],
"shell": false,
"workdir": "/workspace/crabbox",
"env": {"KEY": "value"},
"timeout_secs": 3600,
"sync_delete": true
}
Suggested runner output schema:
{
"exit_code": 0,
"stdout": "optional final stdout",
"stderr": "optional final stderr",
"artifacts": []
}
The provider should fail fast with a clear error if the prediction output does not include a valid command exit code. A Replicate succeeded status should not automatically mean the command passed unless the runner output reports exit code 0.
Implementation plan
1. Add provider package
Add a new package:
internal/providers/replicate/
provider.go
backend.go
client.go
flags.go
core.go
sync.go
*_test.go
Follow delegated provider patterns from:
internal/providers/opencomputer
internal/providers/modal
internal/providers/freestyle
opencomputer is the closest security and REST-client reference because it keeps API keys out of Crabbox config and sends credentials only in request headers.
2. Register provider
Update:
internal/providers/all/all.go, add side-effect import for internal/providers/replicate.
internal/providers/all/all_test.go, add coverage that:
ProviderFor("replicate") resolves.
Name() is replicate.
Family is replicate.
Kind is ProviderKindDelegatedRun.
Coordinator is CoordinatorNever.
- target is Linux.
- features are truthful for the implemented contract.
- no accidental aliases are registered.
- provider implements
DoctorProvider, if the repository's current all-provider doctor contract remains required.
3. Add config and flags
Update internal/cli/config.go with a ReplicateConfig and YAML mapping.
Suggested config fields:
type ReplicateConfig struct {
APIURL string
Deployment string
Version string
Workdir string
WaitSecs int
PollIntervalSecs int
ExecTimeoutSecs int
CancelAfterSecs int
MaxArchiveBytes int64
}
Defaults:
APIURL: https://api.replicate.com
Workdir: /workspace/crabbox
WaitSecs: 60, capped to Replicate's supported wait behavior
PollIntervalSecs: a small nonzero default such as 2
ExecTimeoutSecs: 3600
Credential handling:
- Read token from
CRABBOX_REPLICATE_API_TOKEN, then REPLICATE_API_TOKEN.
- Do not add the API token to
Config, YAML, flags, logs, or command-line arguments.
- Redact the token from HTTP error bodies.
- Refuse cross-origin redirects so the bearer token cannot leak to another host.
Suggested flags:
--replicate-api-url, trusted CLI-only override for tests and development
--replicate-deployment
--replicate-version
--replicate-workdir
--replicate-wait-secs
--replicate-poll-interval-secs
--replicate-exec-timeout-secs
--replicate-cancel-after-secs
--replicate-max-archive-bytes
The implementation should require exactly one of deployment or version unless a future auto-discovery contract is added.
4. Implement REST client
Create a small internal client rather than depending on Replicate SDKs.
Client responsibilities:
- Build requests against the configured API URL.
- Send
Authorization: Bearer <token>.
- Send JSON request bodies.
- Support
Prefer: wait on prediction creation when configured.
- Decode prediction responses, including:
id
status
logs
output
error
urls.get
urls.cancel
- timestamps and metrics when available
- Create predictions through either:
/v1/deployments/{owner}/{name}/predictions
/v1/predictions with a configured version
- Poll prediction state until terminal status.
- Cancel a prediction on context cancellation or
crabbox stop.
- List predictions for
crabbox list, filtering locally when possible to Crabbox-created predictions.
- Redact token values from all surfaced errors.
5. Implement delegated backend
Implement core.DelegatedRunBackend:
-
Warmup
- Validate configuration and token.
- Optionally check the configured deployment/version can be reached.
- Print clearly that Replicate does not create a reusable SSH lease.
- If a runner supports a lightweight health prediction, use it; otherwise avoid consuming GPU time just to warm up.
-
Run
- Reject unsupported delegated sync options using
core.RejectDelegatedSyncOptionsForSpec.
- Build the portable sync archive with existing archive sync helpers.
- Convert the archive into an accepted Replicate file input.
- Create a prediction.
- Treat prediction ID as the run session lease ID, or store a local claim if needed for slug/status/stop consistency.
- Stream or periodically print
logs without duplicating already printed content.
- Map terminal status:
succeeded plus runner exit_code == 0 to Crabbox success.
succeeded plus nonzero runner exit_code to ExitError{Code: exit_code}.
failed to a Crabbox failure with Replicate error/log context.
canceled to a Crabbox canceled/stopped failure.
- Cancel the prediction when the local context is canceled.
-
List
- Return active/recent predictions as
LeaseView entries when identifiable as Crabbox runs.
- Prefer local claims or runner metadata to avoid showing unrelated predictions from the same account.
-
Status
- Resolve a prediction ID or local claim.
- Fetch and map prediction status to
StatusView.
-
Stop
- Resolve a prediction ID or local claim.
- Call prediction cancel.
- Remove local claim only after terminal cancellation or a clear not-found/stale-claim path.
6. Solve archive input strategy
Replicate accepts file inputs as HTTP URLs or data URLs, which is the main design decision for this provider.
Initial safe approach:
- Support data URLs for small archives only.
- Enforce
replicate.maxArchiveBytes.
- Error with a clear message when the archive is too large.
Future larger-workspace approaches:
- Add a signed object storage upload path.
- Use a separate Crabbox-controlled upload endpoint.
- Use a runner-side pull URL if the user's repo or artifact bundle is already available through a short-lived URL.
The first implementation should not silently upload source code to an unspecified third-party store.
7. Add provider docs and provider matrix metadata
Add:
docs/providers/replicate.md
Update:
docs/providers/provider-metadata.json
docs/source-map.md
docs/providers/README.md, generated by node scripts/generate-provider-matrix.mjs
internal/cli/provider_categories_generated.go, generated by the same script
Suggested metadata:
"replicate": {
"status": "built-in",
"category": "delegated-sandbox",
"substrate": "Replicate prediction or deployment backed by a Crabbox runner model",
"location": "cloud",
"ssh": "no",
"sync": "archive-sync",
"gpu": "optional",
"lifecycle": "Replicate prediction",
"cleanup": "prediction cancellation",
"bestFit": "GPU-backed delegated command execution through a purpose-built Replicate runner",
"caveat": "Requires a compatible runner model or deployment; Replicate is not a generic SSH lease",
"docs": "replicate.md"
}
Docs must emphasize:
REPLICATE_API_TOKEN or CRABBOX_REPLICATE_API_TOKEN is required.
- Token should come from a secret manager or environment, not YAML.
- A compatible runner model/deployment is required.
- No SSH, desktop, browser, code-server, or Crabbox-owned rsync support.
- Large workspaces require an upload strategy beyond data URLs.
- Replicate billing behavior may charge for setup, idle, active, failed, and canceled deployment instance time depending on the selected model/deployment.
8. Add tests
Add offline tests for:
- Provider registration and
ProviderSpec.
- Flag application and config validation.
- Token resolution precedence.
- Missing token error.
- API URL validation, including HTTPS-only except loopback development endpoints if desired.
- Cross-origin redirect refusal.
- Authorization header construction.
- Token redaction from JSON and plain-text errors.
- Prediction creation for deployment and version modes.
Prefer: wait header behavior.
- Polling lifecycle mapping for starting, processing, succeeded, failed, and canceled.
- Log streaming deduplication.
- Context cancellation calls prediction cancel.
Stop calls cancel and handles already-canceled/not-found cases safely.
- Archive size enforcement and data URL construction.
- Nonzero runner exit code mapping.
- Malformed runner output error.
- Delegated sync option gating.
Files likely touched
Core/provider registry:
internal/providers/all/all.go
internal/providers/all/all_test.go
internal/cli/config.go
New provider:
internal/providers/replicate/provider.go
internal/providers/replicate/backend.go
internal/providers/replicate/client.go
internal/providers/replicate/flags.go
internal/providers/replicate/core.go
internal/providers/replicate/sync.go
internal/providers/replicate/*_test.go
Docs and generated metadata:
docs/providers/replicate.md
docs/providers/provider-metadata.json
docs/providers/README.md
docs/source-map.md
internal/cli/provider_categories_generated.go
Acceptance criteria
crabbox providers lists replicate with delegated-run, Linux, archive-sync, no SSH, and no coordinator support.
crabbox run --provider replicate -- <command> creates a Replicate prediction against the configured deployment or version.
- The provider uploads or embeds the workspace archive only through an explicit supported input mechanism.
- Replicate prediction logs are streamed or printed in order without repeated log spam.
- Local cancellation cancels the prediction.
crabbox stop <id> cancels the prediction.
crabbox status <id> reports prediction state.
crabbox list --provider replicate does not show unrelated account predictions unless they can be identified as Crabbox-created runs.
- A Replicate
succeeded prediction with runner exit_code != 0 exits Crabbox with that command code.
- API tokens never appear in config, argv, logs, errors, or redirected requests.
- Offline tests cover all client and lifecycle behavior.
- Provider docs clearly state the runner-model requirement and limitations.
Validation before PR
Focused validation:
gofmt -w $(git ls-files '*.go')
go test -race ./internal/providers/replicate ./internal/providers/all ./internal/cli
go vet ./...
node scripts/generate-provider-matrix.mjs
node scripts/check-provider-matrix.mjs
scripts/check-docs.sh
Full validation if the PR also touches worker or broader generated docs:
go test -race ./...
go build -trimpath -o bin/crabbox ./cmd/crabbox
scripts/test-go-modules.sh
scripts/check-go-coverage.sh 90.0
npm ci --prefix worker
npm run format:check --prefix worker
npm run lint --prefix worker
npm run check --prefix worker
npm test --prefix worker
npm run build --prefix worker
node --test scripts/*.test.js
Open questions
- Should the initial provider support only Replicate deployments, or both deployments and direct version predictions?
- What exact runner model schema should Crabbox standardize for archive, command, environment, logs, exit code, and artifacts?
- What maximum data URL archive size is acceptable for the first implementation?
- Is a Crabbox-controlled temporary object store acceptable for larger workspaces, or should large-workspace support be deferred?
- Should
warmup create a lightweight health prediction, or should it only validate configuration to avoid unnecessary GPU billing?
- How should Crabbox tag/filter Replicate predictions so
list and status avoid unrelated account predictions?
Summary
Add a built-in
replicateprovider that can run Crabbox commands through a Replicate prediction or deployment backed by a compatible Crabbox runner model.Replicate is not an SSH host or a general-purpose VM lease API. Its public control plane is centered on predictions, deployments, model versions, logs, output files, cancellation, and optional streaming. Because of that, the provider should be implemented as
ProviderKindDelegatedRun, notProviderKindSSHLease, and should be explicit that it requires a Replicate model or deployment whose input and output schema implements Crabbox's runner contract.Motivation
Crabbox already supports providers that do not expose SSH by using delegated run backends, for example Modal, Freestyle, OpenComputer, CodeSandbox, and Upstash Box. Replicate can fit the same provider family if Crabbox treats Replicate prediction IDs as run/session handles and delegates workspace upload, command execution, log polling, cancellation, and output mapping to a runner model.
This would let users run:
REPLICATE_API_TOKEN=... crabbox run --provider replicate -- npm testor configure a specific deployment:
Replicate API facts
Relevant API and platform details from the Replicate documentation:
Authorization: Bearer $REPLICATE_API_TOKEN.POST https://api.replicate.com/v1/predictions.GET https://api.replicate.com/v1/predictions/{prediction_id}.GET https://api.replicate.com/v1/predictions.POST https://api.replicate.com/v1/predictions/{prediction_id}/cancel.POST https://api.replicate.com/v1/deployments/{deployment_owner}/{deployment_name}/predictions.Prefer: waitfor initial synchronous waiting.Authorizationheader to fetch.Proposed provider shape
Provider metadata
Use canonical provider name
replicatewith no aliases initially.Recommended
ProviderSpec:Do not advertise SSH, desktop, browser, code-server, Crabbox-owned sync, cleanup, pause/resume, run artifacts, or run downloads until those contracts are implemented and tested.
Runner contract requirement
The first implementation should document and enforce that
replicaterequires either:owner/name, that runs a Crabbox runner model, orSuggested runner input schema:
{ "archive": "https://... or data:application/gzip;base64,...", "command": ["npm", "test"], "shell": false, "workdir": "/workspace/crabbox", "env": {"KEY": "value"}, "timeout_secs": 3600, "sync_delete": true }Suggested runner output schema:
{ "exit_code": 0, "stdout": "optional final stdout", "stderr": "optional final stderr", "artifacts": [] }The provider should fail fast with a clear error if the prediction output does not include a valid command exit code. A Replicate
succeededstatus should not automatically mean the command passed unless the runner output reports exit code0.Implementation plan
1. Add provider package
Add a new package:
Follow delegated provider patterns from:
internal/providers/opencomputerinternal/providers/modalinternal/providers/freestyleopencomputeris the closest security and REST-client reference because it keeps API keys out of Crabbox config and sends credentials only in request headers.2. Register provider
Update:
internal/providers/all/all.go, add side-effect import forinternal/providers/replicate.internal/providers/all/all_test.go, add coverage that:ProviderFor("replicate")resolves.Name()isreplicate.Familyisreplicate.KindisProviderKindDelegatedRun.CoordinatorisCoordinatorNever.DoctorProvider, if the repository's current all-provider doctor contract remains required.3. Add config and flags
Update
internal/cli/config.gowith aReplicateConfigand YAML mapping.Suggested config fields:
Defaults:
APIURL:https://api.replicate.comWorkdir:/workspace/crabboxWaitSecs:60, capped to Replicate's supported wait behaviorPollIntervalSecs: a small nonzero default such as2ExecTimeoutSecs:3600Credential handling:
CRABBOX_REPLICATE_API_TOKEN, thenREPLICATE_API_TOKEN.Config, YAML, flags, logs, or command-line arguments.Suggested flags:
--replicate-api-url, trusted CLI-only override for tests and development--replicate-deployment--replicate-version--replicate-workdir--replicate-wait-secs--replicate-poll-interval-secs--replicate-exec-timeout-secs--replicate-cancel-after-secs--replicate-max-archive-bytesThe implementation should require exactly one of
deploymentorversionunless a future auto-discovery contract is added.4. Implement REST client
Create a small internal client rather than depending on Replicate SDKs.
Client responsibilities:
Authorization: Bearer <token>.Prefer: waiton prediction creation when configured.idstatuslogsoutputerrorurls.geturls.cancel/v1/deployments/{owner}/{name}/predictions/v1/predictionswith a configured versioncrabbox stop.crabbox list, filtering locally when possible to Crabbox-created predictions.5. Implement delegated backend
Implement
core.DelegatedRunBackend:WarmupRuncore.RejectDelegatedSyncOptionsForSpec.logswithout duplicating already printed content.succeededplus runnerexit_code == 0to Crabbox success.succeededplus nonzero runnerexit_codetoExitError{Code: exit_code}.failedto a Crabbox failure with Replicate error/log context.canceledto a Crabbox canceled/stopped failure.ListLeaseViewentries when identifiable as Crabbox runs.StatusStatusView.Stop6. Solve archive input strategy
Replicate accepts file inputs as HTTP URLs or data URLs, which is the main design decision for this provider.
Initial safe approach:
replicate.maxArchiveBytes.Future larger-workspace approaches:
The first implementation should not silently upload source code to an unspecified third-party store.
7. Add provider docs and provider matrix metadata
Add:
docs/providers/replicate.mdUpdate:
docs/providers/provider-metadata.jsondocs/source-map.mddocs/providers/README.md, generated bynode scripts/generate-provider-matrix.mjsinternal/cli/provider_categories_generated.go, generated by the same scriptSuggested metadata:
Docs must emphasize:
REPLICATE_API_TOKENorCRABBOX_REPLICATE_API_TOKENis required.8. Add tests
Add offline tests for:
ProviderSpec.Prefer: waitheader behavior.Stopcalls cancel and handles already-canceled/not-found cases safely.Files likely touched
Core/provider registry:
internal/providers/all/all.gointernal/providers/all/all_test.gointernal/cli/config.goNew provider:
internal/providers/replicate/provider.gointernal/providers/replicate/backend.gointernal/providers/replicate/client.gointernal/providers/replicate/flags.gointernal/providers/replicate/core.gointernal/providers/replicate/sync.gointernal/providers/replicate/*_test.goDocs and generated metadata:
docs/providers/replicate.mddocs/providers/provider-metadata.jsondocs/providers/README.mddocs/source-map.mdinternal/cli/provider_categories_generated.goAcceptance criteria
crabbox providerslistsreplicatewith delegated-run, Linux, archive-sync, no SSH, and no coordinator support.crabbox run --provider replicate -- <command>creates a Replicate prediction against the configured deployment or version.crabbox stop <id>cancels the prediction.crabbox status <id>reports prediction state.crabbox list --provider replicatedoes not show unrelated account predictions unless they can be identified as Crabbox-created runs.succeededprediction with runnerexit_code != 0exits Crabbox with that command code.Validation before PR
Focused validation:
Full validation if the PR also touches worker or broader generated docs:
Open questions
warmupcreate a lightweight health prediction, or should it only validate configuration to avoid unnecessary GPU billing?listandstatusavoid unrelated account predictions?