Skip to content

Cloud Agent Workspace and Artifacts

The workspace APIs access the runtime’s files. Artifacts explicitly register output against a run. An agent-created file does not automatically become an artifact. Both live on the runtime, so export important output before deleting its computer.

Use AGENT_ID, RUN_ID, and authentication from the quickstart.

Send an operation to POST /v2/agents/{agent_id}/workspace:

Terminal window
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $RUNTA_TOKEN" \
-H "Content-Type: application/json" \
--data '{"kind":"list_directory","path":"."}' \
"$RUNTA_API_URL/v2/agents/$AGENT_ID/workspace" | jq .

Paths are relative to the guest’s home directory, not Pi’s current repository working directory. Use paths returned by list_directory to navigate to checked out repositories. Absolute paths, .. traversal, and protected .runta paths are rejected.

kind Request fields Relevant response
list_directory Optional path; empty or . means home. entries: names, home-relative paths, kinds, and sizes.
read_text Required nonempty path. text, possibly truncated.
search_files Required nonempty query; optional directory path. matches with path, one-based line, and preview.
read_media Required path; optional nonnegative byte offset, default 0. media_base64, media_type, next_offset.
list_ports No path, query, or offset. ports with port and optional forwardable.

Only search_files accepts query. Only read_media accepts offset. Responses also contain kind, entries, matches, ports, and truncated. Collections not used by an operation are empty.

Example request bodies:

{"kind": "read_text", "path": "notes/summary.txt"}
{"kind": "search_files", "path": ".", "query": "TODO"}
{"kind": "read_media", "path": "screenshots/result.png", "offset": 0}
{"kind": "list_ports"}

The current query helper caps directory listings at 500 entries, text reads at 1 MiB or 20,000 lines, and search results at 100 matches while scanning at most 5,000 files and 256 KiB per file. Narrow the requested directory or query when truncated is true. Text and search responses have no pagination offset.

Media reads support image/video files up to 32 MiB and return chunks up to 2 MiB. Decode each media_base64 chunk separately, append the bytes, and use next_offset as the next request’s offset until truncated is false. forwardable indicates whether a port listens beyond loopback, not whether a public endpoint has been published; see Publish a Service.

Terminal window
printf 'Summary from the client.\n' | base64 | tr -d '\n' |
jq -Rs '{path: "notes/summary.txt", content_base64: .}' |
curl --fail-with-body --silent --show-error -X PUT \
-H "Authorization: Bearer $RUNTA_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @- \
"$RUNTA_API_URL/v2/agents/$AGENT_ID/workspace/files"

The helper creates parent directories and overwrites an existing file. The 200 response contains the requested path and decoded byte size. The decoded helper limit is 32 MiB, but the HTTP request limit can be smaller. See Limits.

Terminal window
curl --fail-with-body --silent --show-error -X DELETE \
-H "Authorization: Bearer $RUNTA_TOKEN" \
-H "Content-Type: application/json" \
--data '{"path":"notes/summary.txt","recursive":false}' \
"$RUNTA_API_URL/v2/agents/$AGENT_ID/workspace/files"

Success returns 204 with no response body. Use recursive: true to remove a directory and its contents. Deleting the workspace root is rejected. Files are shared by every harness on the runtime.

Register a local file against a run belonging to this agent:

Terminal window
base64 < report.txt | tr -d '\n' |
jq -Rs --arg run "$RUN_ID" '{
run_id: $run,
name: "report.txt",
media_type: "text/plain",
content_base64: .
}' |
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $RUNTA_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @- "$RUNTA_API_URL/v2/agents/$AGENT_ID/artifacts" |
jq .

Success returns 201 with id, run_id, harness_id, name, media_type, size, and created_at. Save id as ARTIFACT_ID. media_type defaults to application/octet-stream.

Names must match [A-Za-z0-9][A-Za-z0-9._-]{0,254}: a single filename, without directory separators. Content is raw base64. The helper caps decoded artifacts at 32 MiB; this does not override request or response transport limits.

Terminal window
curl --fail-with-body --silent --show-error --get \
-H "Authorization: Bearer $RUNTA_TOKEN" \
--data-urlencode "run_id=$RUN_ID" \
"$RUNTA_API_URL/v2/agents/$AGENT_ID/artifacts" | jq .

Listing returns an array, newest first, without content. run_id is optional: without it the current implementation lists artifacts across the backing runtime. Include it when presenting one run’s results.

Terminal window
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $RUNTA_TOKEN" \
"$RUNTA_API_URL/v2/agents/$AGENT_ID/artifacts/$ARTIFACT_ID?include_content=true" |
jq .

include_content defaults to false. Setting it to true adds content_base64 to the metadata response; decode it in your client to obtain the file. Download and deletion check that the artifact belongs to the addressed harness. The artifact endpoint has no chunked download mode. For large workspace media, use read_media instead.

Terminal window
curl --fail-with-body --silent --show-error -X DELETE \
-H "Authorization: Bearer $RUNTA_TOKEN" \
"$RUNTA_API_URL/v2/agents/$AGENT_ID/artifacts/$ARTIFACT_ID"

Success returns 204. This removes the registered artifact and its stored copy, without deleting its run or the original workspace file.