Push and deploy
This group covers getting any agent to run on a customer’s data: push and deploy a version, then have the vault owner connect it.
Shipping has three steps, and they are the same for code agents and workflows:
| Step | What it does | CLI | ROC |
|---|---|---|---|
| Build | Bundles the code and writes manifest.json. |
cef build |
The Workflow Builder builds from the canvas. |
| Push | Uploads a version to the Agent Service’s DDC bucket, the registry. Versions are immutable. | cef push |
Part of Deploy in the Workflow Builder. |
| Deploy | Applies deployment records: which version runs, for which vaults and events. | cef deploy |
Agent page → Overview → deployments; Deploy in the Workflow Builder. |
Then a vault owner must connect the agent before it runs on their data. See Connect to a vault.
Before you start
From ROC, open your Agent Service → ⋯ → Settings → General and copy:
- Agent-service public key: pass it as
--as-pubkey. - Registry bucket ID: pass it as
--bucket.
On the Access tab, generate two tokens:
| Token | Used by | Environment variable |
|---|---|---|
| DDC access token | cef push, cef widget push, cef cubby push |
CEF_DDC_ACCESS_TOKEN |
| CLI access token | cef deploy, cef publish |
CEF_ACCESS_TOKEN |
Tokens are shown once. Members of an Agent Service get their DDC token through an invite; see Team.
Environments
Every command takes --env dev|stage|prod (or $CEF_ENV). The default is dev. One flag selects the whole environment: the DDC network for push (dev = devnet, stage = testnet, prod = mainnet), the platform API for deploy, and the endpoints baked into widgets. Push and deploy to the same environment.
Build
cef buildWrites dist/<alias>/bundle.js, manifest.json, and widgets/<id>/ for every agent in cef.config.ts. A workflow written with defineWorkflow builds the same way; its graph and the workflow runner become the bundle. Build errors are listed in Write an agent.
Push
export CEF_DDC_ACCESS_TOKEN=…cef push --env dev --bucket <bucketId> --as-pubkey <agentServicePubkey>cef push:
- uploads
bundle.jsand each widget directory, content-addressed; - writes
manifest.jsonunderagents/<alias>/<version>/in the bucket and moveslatestto it; - stamps the agent id
<agentServicePubkey>:<alias>and the environment’s endpoints into the manifest and widgets; - declares any cubby the manifest names that the bucket does not have yet.
A push body is capped at 64 MiB. Ship large assets as vault objects, not in the bundle.
Before uploading anything, cef push checks the access token against the bucket’s on-chain owner. A token that the owner did not issue is refused with the owner’s address and the fix. See Team.
Bump version in cef.config.ts for each push you want to keep. An A2A agent you run elsewhere is registered with --kind external; see Bring your own (A2A).
Deploy
export CEF_ACCESS_TOKEN=…cef deploy --env dev --as-pubkey <agentServicePubkey>cef deploy reads every record in deployments/ and applies them as one set, replacing what is live. The folder is the desired state: delete a file and the next deploy removes that record. Each apply creates a revision you can roll back to in ROC.
Deployment records
One record per file; the filename is the record name (^[a-z0-9][a-z0-9_-]{0,62}$). .json and .jsonc are read, comments allowed.
{ "priority": 99, "targeting": "", // empty: the default record, matches everything "version": "latest", "weight": 1}{ "priority": 10, "targeting": "vault.scope == 'sandbox'", "version": "0.2.0", "weight": 1, "params": { "temperature": 0.1 }}| Field | Required | Rule |
|---|---|---|
priority |
yes | Among matching records, the lowest priority wins. |
targeting |
yes | A CEL expression over vault (id, scope), event (type), and connection.settings. "" marks the default record. |
version |
yes | A pushed semver, or "latest". |
weight |
no | A positive integer, default 1. Records in the same priority tier split traffic by weight: 90 and 10 is a 90/10 split. |
enabled |
no | false excludes the record. |
params |
no | Overrides the manifest’s param defaults. |
engagements |
no | Per-engagement overrides: { "<id>": { priority, weight, limit: { n, per }, enabled, params } }. |
expiresAt |
no | RFC 3339. Once past, the record is ignored. |
The set must contain exactly one default record (empty targeting). A Job resolves its version when it is created and keeps it until it ends, so "latest" affects new Jobs only.
| Flag | Default | Meaning |
|---|---|---|
--version <v> |
— | Override version in every record without editing files. |
--deployments <path> |
deployments |
A folder, or one file holding { "deployments": [...] } or a single record. |
--dry-run |
— | Print the assembled set; apply nothing. |
--note, --author |
git user.email |
Recorded on the revision. |
Rollout patterns
| Goal | Records |
|---|---|
| Ship to everyone | One default record, version pinned or "latest". |
| Canary to an audience | Add a record with targeting and a lower priority than the default. |
| Percentage rollout | Two records in one priority tier with weights such as 90 / 10. |
| Temporary experiment | Add expiresAt. |
In ROC
Open Agents, pick the agent, and use the deployments manager on Overview: New deployment, Edit deployment, Delete deployment, and History with Roll back. The form has Route (Name, Audience — targeting (CEL), Version, Priority, Weight), Parameters, Engagements, and Execution rules. Saving creates a new revision.
Workflows
A workflow is an agent, so the same steps apply.
- In code:
defineWorkflowincef.config.ts, thencef build,cef push,cef deploy. See Workflows in code. - In the Workflow Builder: Deploy {version} writes the canvas as a new version, makes it live, and connects it to your vault. The tooltip reads “Write this canvas as a new version and make it live”. Run stays disabled until the workflow is deployed.
Listing
cef publish sends the agent’s card to the marketplace listing, and the agent page’s Pricing tab publishes its pricing. Neither is needed to deploy, connect, or run the agent.