Agents and functions
This page documents every platformctl command that works on agents and functions: what it does, its flags, and what its output looks like. Agents and functions share one command surface — a function is deployed with functions deploy, then managed with the same status, logs, invoke, and delete verbs as an agent.
All commands here honor the global flags (--api, --project, -o). Management commands (everything except invoke) need a credential; invoke works without one by default.
Command summary
| Command | What it does | Credential |
|---|---|---|
platformctl deploy <dir> | Package, upload, build, and start an agent | Required |
platformctl functions deploy <dir> | Same, for a one-file function | Required |
platformctl list | List all agents and functions | Required |
platformctl status <agent> | Show one agent's full state | Required |
platformctl invoke <agent> <message> | Send a message, print the reply | Not required (by default) |
platformctl memorize <agent> --session <id> | Save a session to long-term memory | Required |
platformctl secrets set <agent> KEY=VALUE... | Add or update secrets | Required |
platformctl logs <agent> | Read logs (live, follow, or persisted) | Required |
platformctl delete <agent> | Delete an agent or function | Required |
platformctl demo | Narrated end-to-end walkthrough | Required (it deploys) |
platformctl deploy
Packages a directory of agent code, uploads it, and waits until the agent is running.
platformctl deploy <dir> [--name <name>] [--framework adk|langgraph|crewai]
| Flag | Default | What it does |
|---|---|---|
--name | The directory's base name | The agent's name. Must be a lowercase DNS label matching ^[a-z]([a-z0-9-]{0,61}[a-z0-9])?$: start with a lowercase letter, end with a lowercase letter or digit (never a hyphen), use only a-z, 0-9, and - in between, at most 63 characters. |
--framework | Auto-detected | Which agent library your code uses: adk, langgraph, or crewai. Auto-detection: a crew.py file means crewai, a graph.py file means langgraph, anything else means adk. |
What happens: the CLI tars the directory's contents in memory (symlinks preserved, entries relative to the directory), uploads via POST /v1/agents with a 2-minute request timeout, prints the accepted build id, then polls the agent's status every 2 seconds for up to 5 minutes, printing each transition.
Example:
platformctl deploy examples/agents/research-buddy --name research-buddy
You should see:
packaging examples/agents/research-buddy...
uploading research-buddy (4.2 KiB, framework=adk)...
build b-1a2b3c accepted
status: -> building
status: building -> deploying
status: deploying -> ready
research-buddy is ready at http://research-buddy.cai-p-xxxx.svc.cluster.local
If the build or deploy fails:
research-buddy failed to build/deploy (see `platformctl logs research-buddy`)
If it does not become ready in time:
timed out after 5m0s waiting for research-buddy (last status: building)
With the legacy --json flag, the final stdout line is {"name","status":"ready","image","url"} as one compact JSON object.
There is no ignore mechanism. A stray .venv/ or node_modules/ ships with your code and can blow the 100 MiB upload cap. Deploy from a clean directory.
Notes:
- Upload cap: 100 MiB by default (the server's
MAX_UPLOAD_BYTESsetting), plus 1 MiB slack for form fields. - An invalid name returns
400with:missing or invalid 'name' (must be a lowercase DNS label). (Commands that address an existing agent by name —status,invoke,logs,delete— returninvalid agent name (must be a lowercase DNS label)instead.) - Auto-detection can surprise you: a stray
crew.pyin an ADK agent directory deploys it as CrewAI. Pass--frameworkto be explicit. - The
202response from upload carries no status — status comes only from the polling that follows.
See also: deploying agents and the agent quickstart.
platformctl functions deploy
Deploys a one-file HTTP function. A function is a directory with a single handler file that exposes one function the platform calls for each request.
platformctl functions deploy <dir> [--name <name>] [--runtime python]
| Flag | Default | What it does |
|---|---|---|
--name | The directory's base name | The function's name. Same lowercase-DNS-label rule as agents. |
--runtime | python (auto-detected) | Only python works today. The CLI accepts nodejs, go, and ruby and folds them into the framework tokens function-nodejs, function-go, and function-ruby, which POST /v1/agents currently rejects with unsupported 'framework': one of "adk", "langgraph", "crewai", "function". The same rejection happens automatically if your directory contains handler.js, handler.go, or handler.rb instead of handler.py. Deploy non-Python functions through the API by sending framework=function plus a separate runtime form field. |
Functions ride the same upload path as agents — POST /v1/agents with a framework form field — with the same polling, output, and 100 MiB cap as deploy. The CLI folds the runtime into that framework field and never sends a separate runtime field: python becomes function, and nodejs, go, and ruby become function-nodejs, function-go, and function-ruby. An unrecognized --runtime value is passed through raw into the same field. The server checks framework before it ever looks at a runtime field, so an unknown --runtime fails with the framework error, not a runtime error:
unsupported 'framework': one of "adk", "langgraph", "crewai", "function"
The server does have an unsupported 'runtime': one of "python", "nodejs", "go", "ruby" message, but only API callers reach it — it needs framework=function plus a separate runtime field in the same request, which the CLI never sends.
Example:
mkdir hello-http
cat > hello-http/handler.py <<'EOF'
def handle(event):
return {"echo": event.get("message", "")}
EOF
platformctl functions deploy ./hello-http --name hello-http
You should see the same build ... accepted and status: transitions as an agent deploy, ending with:
hello-http is ready at http://hello-http.cai-p-xxxx.svc.cluster.local
Notes:
- Agents and functions share one flat name space per project — a function cannot reuse an agent's name.
- Redeploying means running
functions deployagain (or "Update source" in the console); the console's agent "redeploy" shortcut is disabled for functions.
See also: the function quickstart and runtimes.
platformctl list
Lists every agent and function in the project. The CLI follows pagination to the end, so you always see everything, not just the first 50.
platformctl list
Example:
platformctl list
You should see:
NAME STATUS URL
research-buddy ready http://research-buddy.cai-p-xxxx.svc.cluster.local
If nothing is deployed: no agents deployed. With -o json or -o yaml you get the agent objects the CLI decodes: name, status, url, framework, image, message, created_at, and updated_at. Fields the API returns but the CLI's Agent struct does not decode — kind, runtime, external_url, public_url, latest_revision, and owner — are silently dropped and visible only through the raw API (GET /v1/agents) or the console.
platformctl status
Shows one agent's or function's full state.
platformctl status <agent>
The default output is a generic field/value table. Use -o json for the same object as JSON:
platformctl status research-buddy -o json
You should see a JSON object with exactly these fields: name, framework, status, url, image, message, created_at, and updated_at. The status values are building, deploying, ready, and failed; when failed, the message field carries the last error. As with list, the API's kind, runtime, external_url, public_url, and latest_revision fields are dropped by the CLI — read them from GET /v1/agents/{name} or the console.
platformctl invoke
Sends one message to a deployed agent or function and prints the reply. This is the one command that works without a credential (the platform's data plane is open by default; an administrator can close it with the server-side INVOKE_AUTH_REQUIRED=true setting).
platformctl invoke <agent> <message> [--session <id>] [--memorize]
| Flag | Default | What it does |
|---|---|---|
--session | none — the server starts a new session | Continue an existing conversation. A session is one ongoing conversation, identified by a session_id; the platform stores its history so follow-up questions have context. |
--memorize | off | Also save this exchange to the agent's long-term memory immediately. |
The client waits up to 5 minutes — generous on purpose, because an idle agent has to cold-start.
Example:
platformctl invoke research-buddy "My boat is a Mastercraft Maristar 245. Compute 2**32 in python."
You should see:
4294967296 ...
(session: 9f2c...)
tool_call: run_python ...
The answer comes first, then the session id, then one tool_call: <name> <summary> line per tool the agent used. Continue the conversation by passing the session id back:
platformctl invoke research-buddy "What boat do I have?" --session 9f2c...
With the legacy --json flag, the machine-readable shape is {"session_id","response","tool_calls":[names]}.
Functions are invoked the same way — platformctl invoke hello-http "ping" — because functions share the invoke path.
platformctl invoke waits for the complete answer. Live token-by-token streaming (POST /v1/agents/<name>/invoke/stream, NDJSON) is available through the API and the example Python client, not the Go CLI. See invoking agents.
platformctl memorize
Copies a session's conversation into the agent's long-term memory, so future new sessions can recall it.
platformctl memorize <agent> --session <id>
| Flag | Default | What it does |
|---|---|---|
--session | none — required | The session to save. Missing it fails with: --session is required. |
Unlike invoke, memorize always requires a credential — it writes to the agent's memory.
Example:
platformctl memorize research-buddy --session 9f2c...
You should see the server's own message if it returns one, otherwise:
memorized session 9f2c... for research-buddy
See also: agent memory and sessions.
platformctl secrets set
Adds or updates secrets on an agent or function. Secrets become environment variables in the workload, and each change rolls a new revision.
platformctl secrets set <agent> KEY=VALUE [KEY=VALUE...]
Example:
platformctl secrets set research-buddy DEMO_TOKEN=abc123
You should see:
set 1 secret(s) for research-buddy
A malformed pair fails with:
invalid KEY=VALUE pair: "DEMO_TOKEN"
Notes:
secrets setmerges. It callsPATCH /v1/agents/<name>/secretswith only the keys you name and never deletes other keys — so it can never wipe the platform-managedMODEL_API_KEY.- There are no
secrets listorsecrets deletesubcommands in the CLI. Listing and deleting secrets is console/API only — see secrets and environment variables.
platformctl logs
Reads an agent's or function's logs.
platformctl logs <agent> [-f|--follow] [--history]
| Flag | Default | What it does |
|---|---|---|
-f, --follow | off | Tail the live pod's log stream. Runs with no timeout — stop it with Ctrl-C. |
--history | off | Print persisted log lines that survive scale-to-zero and revision rollouts. |
The two flags are mutually exclusive:
--follow and --history are mutually exclusive: --history reads persisted logs, --follow tails the live pod
Example:
platformctl logs research-buddy --history
You should see one line per persisted entry, formatted as <ts> <stream> <message>, or:
no persisted logs
An agent that has scaled to zero has nothing for plain logs or --follow to read. Use --history to see what it logged before it went idle.
See also: logs.
platformctl delete
Deletes an agent or function.
platformctl delete <agent>
Example:
platformctl delete research-buddy
You should see:
deleted research-buddy
platformctl demo
Runs a narrated end-to-end walkthrough of the golden path. It takes no flags.
platformctl demo
It runs five narrated steps: deploy the example agent if needed, invoke it in a new session, ask a follow-up in the same session, memorize the session, then recall the memory in a fresh session.
demo must be run from inside the platform repository — it looks for examples/agents/research-buddy in the current directory or a parent (walking up to 8 levels). Otherwise it fails with:
could not find examples/agents/research-buddy under the current directory or any parent (run `platformctl demo` from inside crusoe-ai-platform)
Working with sessions
There is no platformctl sessions command group. Sessions are created and continued through invoke:
- Invoke without
--sessionand the server mints a new session id, printed as(session: <id>). - Pass that id back with
--sessionto continue the conversation. - Use
memorize(orinvoke --memorize) to promote a session into long-term memory.
The CLI cannot list or inspect a session's stored history. See sessions for how session storage works.
Console/API only
These agent capabilities exist on the platform but have no CLI command:
| Capability | Where to do it |
|---|---|
| List or delete secrets | Console, or the API — see secrets and environment variables |
| Edit an agent's files in place | Console — see files and the editor |
| Split traffic between revisions | Console, or the API — see traffic and revisions |
| Streaming invoke (NDJSON) | API — see invoking agents |
For the underlying endpoints, see the agents API reference.