@delta-agentcloud/cli 1.1.20 → 1.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,19 +2,6 @@
2
2
 
3
3
  Command-line tool for the Delta Agent Cloud, used to manage Delta Sandbox GPU/CPU compute workloads and invoke Science tools.
4
4
 
5
- ## v1.1.19 Release Notes
6
-
7
- - `feat(config)`: `delta-cli config init` and the install wizard now write a default `base_url` automatically, removing the manual first-use configuration step.
8
- - Added the `delta-protein` skill: 40+ protein structure prediction/design/analysis tool references and cross-tool workflows.
9
- - Updated the `xrd` science reference (cloud XRD phase identification, artifacts, CIF simulation and refinement contract).
10
- - Internal: public repository sync and release pipeline improvements (sync planner and unit tests).
11
-
12
- ## v1.1.18 Release Notes
13
-
14
- - Translate the three active agent skills (`delta-shared`, `delta-sandbox`, and `delta-science`) and their maintained references into English.
15
- - Validate representative agent workflows for authentication-state reporting, sandbox resource discovery, live Science catalogue discovery, and safe handling of tools without a request schema.
16
- - Include all three skill directories in the source release commit and regenerate platform binary checksums as part of the release.
17
-
18
5
  ## Installation
19
6
 
20
7
  ### Option 1: npx one-click install (recommended)
@@ -257,6 +244,8 @@ delta-cli sandbox kill <sandbox_id>
257
244
 
258
245
  > **Tip**: `sandbox list` (list sandbox instances) differs from `sandbox ls <id>` (list a directory); don't confuse them.
259
246
 
247
+ > **Paths inside the sandbox**: a path that points *inside* the sandbox (`--path`, the remote part of `write-multiple --entry`, `upload --target`, `pull --source`, `run`/`run-bg --log-file`) is prefixed with the sandbox working directory when it is relative, and absolute paths are used as-is; paths that point at the *local* machine (`write --source`, `upload --source`, `pull --target`, `read --output`) are local and are never rewritten.
248
+
260
249
  | Command | Description |
261
250
  |---------|-------------|
262
251
  | `delta-cli sandbox list` | List the current user's sandbox instances |
@@ -330,9 +319,11 @@ All commands return a unified JSON envelope:
330
319
  {"ok":true,"data":{"id":"sb-xxx","status":"running"}}
331
320
 
332
321
  // error
333
- {"ok":false,"error":{"type":"auth","message":"not authenticated","hint":"run 'delta-cli auth login'"}}
322
+ {"ok":false,"error":{"type":"auth","message":"not authenticated","hint":"run 'delta-cli auth login'","request_id":"create_a1b2c3"}}
334
323
  ```
335
324
 
325
+ `error.hint` gives the actionable next step (for a failed create it names the concrete cause - for example, the image was not cached on the target node, so retry or pick a GPU type whose node already has the image), and `error.request_id` identifies the same failure in the server log.
326
+
336
327
  Error types and exit codes:
337
328
 
338
329
  | Type | Exit Code | Scenario |
package/checksums.txt CHANGED
@@ -1,5 +1,5 @@
1
- a23b892ef6d9d6f18a4c5deaeb6b79cc8ea0bf9ffb92d45e9941dd83b8243a26 delta-cli-darwin-amd64.tar.gz
2
- b9140e0c10dc110bfdaf595109a61c7cbc5dd2b793e4b902528c46db7565bb84 delta-cli-darwin-arm64.tar.gz
3
- 509b42c6ffd6f7179f08022127ab887b7ca6776fe18742dd9221aa85ccfa3084 delta-cli-linux-amd64.tar.gz
4
- 30da74a6764e7cf4878615a0e621de38787cee60747e516f444bacdf0e985ad6 delta-cli-linux-arm64.tar.gz
5
- 397155b156e3b9c4414e4e238254161e0426e87eca90a36c4552b9551beccfec delta-cli-windows-amd64.zip
1
+ ae8095f3a2c9dc94ee4167bae557a86f1907093eeba3d84cef61ab4f85a17e4f delta-cli-darwin-amd64.tar.gz
2
+ 371e22d3b7b72586dd3d9d2886ad1c9ab73e1e620a8f62247b8d6a7f3257321f delta-cli-darwin-arm64.tar.gz
3
+ add5f9953d771fc13164aa4bee8dffc103f281213f704b4b5ef08118a80f3637 delta-cli-linux-amd64.tar.gz
4
+ 4f57edbbde69750ee8052a14fb56c09cc3bc5d24f02e5aca4ae08460c1ba69a0 delta-cli-linux-arm64.tar.gz
5
+ fd6261b30d542ccf6bfa13722060a502b97697407efea22b7755632d998fe573 delta-cli-windows-amd64.zip
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delta-agentcloud/cli",
3
- "version": "1.1.20",
3
+ "version": "1.1.24",
4
4
  "description": "Delta Agent Cloud CLI for sandbox compute and science tools.",
5
5
  "bin": {
6
6
  "delta-cli": "scripts/run.js"
@@ -164,7 +164,7 @@ The reason is that, after running a command, this skill reads `log_file` from th
164
164
  | Read a file | `sandbox read <id> --path <path> [--output <local-path> --tail N --grep <pattern> --offset N --limit N --context N --max-bytes N --parse-json]` |
165
165
  | Pull a file/directory | `sandbox pull <id> --source <sandbox-path> --target <local-path> [--recursive] [--pattern <glob>]` — pull a single file or recursively pull a directory, with sha1 verification (the reverse of upload: source=remote, target=local) |
166
166
  | View the working directory | `sandbox working-directory <id>` (returns `data.path`, such as `/workspace/{user_id}/{sandbox_id}`) |
167
- | Write a file | `sandbox write <id> --source <filename>` (without `--path`, writes to the working directory by default); a relative `--path <path>` is prefixed with the working directory, while an absolute path is used as given |
167
+ | Write a file | `sandbox write <id> --source <filename>` (without `--path`, writes to the working directory by default); **every sandbox-side path** — `--path`, the remote part of `write-multiple --entry`, `upload --target`, `pull --source`, `run`/`run-bg --log-file` — is prefixed with the working directory when relative, while an absolute path is used as given |
168
168
  | Write multiple files | `sandbox write-multiple <id> --entry <remote-path>=<local-path> [--entry ...]` |
169
169
  | Upload a directory | `sandbox upload <id> --source <local-directory> --target <sandbox-path>` |
170
170
  | List a directory | `sandbox ls <id> --path <path>` (defaults to `.`) |
@@ -176,7 +176,6 @@ The reason is that, after running a command, this skill reads `log_file` from th
176
176
  | Delete directories | `sandbox rmdir <id> --path <path> [--path ...]` |
177
177
  | Create directories | `sandbox mkdir <id> --path <path> [--path ...]` |
178
178
  | Search files | `sandbox search <id> --path <root-directory> --pattern <glob>` |
179
- | Upload a directory | `sandbox upload <id> --source <local-directory> --target <sandbox-path>` |
180
179
 
181
180
  ## Full lifecycle
182
181
 
@@ -195,7 +194,7 @@ The reason is that, after running a command, this skill reads `log_file` from th
195
194
  - `--no-auto-cleanup`: when this flag is set, the sandbox **will not be cleaned up automatically** (both server-side timeout reclamation and the local periodic `cleanup_stale` process are skipped). It can be destroyed only by an explicit `sandbox kill`/`finish`. Use this only when the task genuinely needs to survive past periodic cleanup; you must destroy it explicitly when the task is done to avoid leaking resources.
196
195
  - **Do not repeatedly poll with `sandbox status` after a successful create**. The sandbox is ready as soon as `sandbox create` returns; use its returned `data.sandbox_id` directly for `write`/`run`. Extra polling adds tool calls without providing any benefit.
197
196
  3. **Write code/data**:
198
- - **Single file**: `delta-cli sandbox write <id> --source <filename>` — omit `--path` to write to the sandbox's working directory by default (`/workspace/{user_id}/{sandbox_id}/`; query it with `delta-cli sandbox working-directory <id>`). Pass only a local filename to `--source` (for example, `--source train.py`). **Do not** use shell-variable paths such as `"$WORKSPACE_ROOT/train.py"` or `$(pwd)/train.py`. With `--source`, the CLI reads the local file itself without shell expansion, making this the safest option. If you need a specific path, a relative `--path <relative-path>` is automatically prefixed with the working directory; absolute paths are used as given (**avoid** paths such as `/workspace/<filename>` outside `{user_id}`, as they do not persist after `kill`). The returned `size` field is the actual number of bytes on disk (verified with stat), so you can check that the write is complete. For small configuration files (<20 lines), you may use `--data "..."`, but you must also pass `--path`. File paths and extensions depend on the runtime in the image.
197
+ - **Single file**: `delta-cli sandbox write <id> --source <filename>` — omit `--path` to write to the sandbox's working directory by default (`/workspace/{user_id}/{sandbox_id}/`; query it with `delta-cli sandbox working-directory <id>`). Pass only a local filename to `--source` (for example, `--source train.py`). **Do not** use shell-variable paths such as `"$WORKSPACE_ROOT/train.py"` or `$(pwd)/train.py`. With `--source`, the CLI reads the local file itself without shell expansion, making this the safest option. If you need a specific path, a relative `--path <relative-path>` is automatically prefixed with the working directory; absolute paths are used as given (the same rule applies to every sandbox-side path: the remote part of `write-multiple --entry`, `upload --target`, `pull --source`, and `run`/`run-bg --log-file`) (**avoid** paths such as `/workspace/<filename>` outside `{user_id}`, as they do not persist after `kill`). The returned `size` field is the actual number of bytes on disk (verified with stat), so you can check that the write is complete. For small configuration files (<20 lines), you may use `--data "..."`, but you must also pass `--path`. File paths and extensions depend on the runtime in the image.
199
198
  - **Write multiple files**: `sandbox write-multiple <id> --entry <remote-path>=<local-path> [--entry ...]` (remote path is on the left of `=`, local path on the right; bulk writes with `--data` are not supported)
200
199
  - **Upload a directory**: `sandbox upload <id> --source <local-directory> --target <sandbox-path>` — the CLI packages the local directory as tar.gz and uploads it using multipart/form-data; the server extracts it into the target directory. The response lists each file's path, size and mode. After upload, the CLI checks the local and remote file lists for integrity and warns about mismatched sizes, extra files and similar issues.
201
200
  - **Note**: `--source` is a **local directory path**; `--target` is the **target directory inside the sandbox**. The target directory is created if it does not exist.
@@ -383,6 +382,7 @@ This skill is designed to make the conclusion self-contained: when execution end
383
382
  | `error.type: validation` | Check parameter formats and required flags |
384
383
  | `error.type: auth / permission` | Follow the permission-denied guidance in delta-shared |
385
384
  | `error.type: api` (5xx) | Server error; check the API service status |
385
+ | `sandbox create` failed | Read `error.hint` — it states the cause and the next step (for example, the image was not cached on the target node, so the initial pull exceeded the readiness timeout: retry once, or pick a GPU type whose node already has the image). A failed create leaves no sandbox behind, so retrying is safe. `error.request_id` identifies the failure in the server log. |
386
386
  | Command execution failed (`exit_code ≠ 0`) | Check stdout/stderr returned by `run` |
387
387
  | Command timed out | Increase `--timeout` or use `run-bg` |
388
388
  | `error.type: internal` | Client-side internal error; check the delta-cli version or contact the maintainer |
@@ -1,5 +1,7 @@
1
1
  > **Prerequisite:** Read [`../../delta-shared/SKILL.md`](../../delta-shared/SKILL.md) first for authentication, configuration and general error handling.
2
2
 
3
+ > **Paths inside the sandbox:** every path that points *inside* the sandbox — `--path`, the remote part of `write-multiple --entry`, `upload --target`, `pull --source`, and `run`/`run-bg --log-file` — is resolved against the sandbox working directory when it is relative; an absolute path is used as-is. Flags that point at the *local* machine (`write --source`, `upload --source`, `pull --target`, `read --output`) are local and are never rewritten.
4
+
3
5
  # Command reference
4
6
 
5
7
  ## Discovery
@@ -15,11 +17,12 @@
15
17
 
16
18
  | Command | Description |
17
19
  |------|------|
18
- | `sandbox create --image-name <image-name> [--cpu N --memory XGi --gpu N --gpu-mem N --gpu-type <model> --shm-size XGi --devices kvm --max-life M --no-auto-cleanup]` | Create a sandbox container (`--image-name` takes an image name, such as `"PyTorch CUDA13 (GPU)"`; the underlying image identifier is hidden from users. `--gpu-type` selects a GPU model, such as `"RTX 4090"` or `H100`; the server maps this to the HAMi use-gputype annotation for model-based scheduling. To see available models, check `sandbox resources` (the `third_party` group's `gpu_types[].gpu_name`); if omitted, scheduling is automatic. `--no-auto-cleanup` prevents automatic cleanup; the sandbox can then be destroyed only with an explicit kill/finish); `--memory`/`--gpu-mem` accept g/m/G/M formats (for example, `1G`/`512M`; lowercase is also accepted), which the CLI converts to the `Gi`/`Mi` units accepted by the server; `--shm-size` increases the container's `/dev/shm` (the **default is only 64Mi**; it must be increased if PyTorch `DataLoader(num_workers>0)`/`multiprocessing`, Chromium-based engines or similar report `No space left on device`/`Bus error` because shared memory is insufficient; **a Gi/Mi unit is required** (`4G`/`512M` are normalised by the CLI; the server rejects a bare number); it **must not exceed `--memory`** (it is a memory filesystem and filling it causes OOMKill; `--memory` defaults to only `1Gi`, so increasing shm usually requires increasing memory too); validation is backend-independent and rejects invalid values before creation, but this setting is applied only on private compute (third-party compute ignores it); `--devices` requests host-device passthrough using comma-separated tokens (for example, `kvm` makes `/dev/kvm` available inside the container for nested virtualisation; this raises privileges, and if the server allowlist is not enabled, creation is **explicitly rejected** rather than silently ignored; this setting is applied only on private compute); **resource limits per sandbox**: `--cpu` ≤ 512, `--memory` ≤ 1024Gi, `--gpu` ≤ 64, `--gpu-mem` ≤ 1024Gi, and `--shm-size` ≤ `--memory`. Exceeding a limit returns a **validation error promptly at request time** (it does not hang); normal tasks are well below these limits. The response echoes the requested image name/resource (request values fill fields not returned by the server; server values take precedence); compute backend is an internal detail and is selected automatically, so `--provider` is no longer supported. |
20
+ | `sandbox create --image-name <image-name> [--cpu N --memory XGi --gpu N --gpu-mem N --gpu-type <model> --shm-size XGi --devices kvm --max-life M --no-auto-cleanup]` | Create a sandbox container (`--image-name` takes an image name, such as `"PyTorch CUDA13 (GPU)"`; the underlying image identifier is hidden from users. `--gpu-type` selects a GPU model, such as `"RTX 4090"` or `H100`; the server maps this to the HAMi use-gputype annotation for model-based scheduling. To see available models, check `sandbox resources` (the `third_party` group's `gpu_types[].gpu_name`); if omitted, scheduling is automatic. `--no-auto-cleanup` prevents automatic cleanup; the sandbox can then be destroyed only with an explicit kill/finish); `--memory`/`--gpu-mem` accept g/m/G/M formats (for example, `1G`/`512M`; lowercase is also accepted), which the CLI converts to the `Gi`/`Mi` units accepted by the server; `--shm-size` increases the container's `/dev/shm` (the **default is only 64Mi**; it must be increased if PyTorch `DataLoader(num_workers>0)`/`multiprocessing`, Chromium-based engines or similar report `No space left on device`/`Bus error` because shared memory is insufficient; **a Gi/Mi unit is required** (`4G`/`512M` are normalised by the CLI; the server rejects a bare number); it **must not exceed `--memory`** (it is a memory filesystem and filling it causes OOMKill; `--memory` defaults to only `1Gi`, so increasing shm usually requires increasing memory too); validation is backend-independent and rejects invalid values before creation, but this setting is applied only on private compute (third-party compute ignores it); `--devices` requests host-device passthrough using comma-separated tokens (for example, `kvm` makes `/dev/kvm` available inside the container for nested virtualisation; this raises privileges, and if the server allowlist is not enabled, creation is **explicitly rejected** rather than silently ignored; this setting is applied only on private compute); **resource limits per sandbox**: `--cpu` ≤ 512, `--memory` ≤ 1024Gi, `--gpu` ≤ 64, `--gpu-mem` ≤ 1024Gi, and `--shm-size` ≤ `--memory`. Exceeding a limit returns a **validation error promptly at request time** (it does not hang); normal tasks are well below these limits. The response echoes the requested image name/resource (request values fill fields not returned by the server; server values take precedence); compute backend is an internal detail and is selected automatically, so `--provider` is no longer supported. If creation fails, `error.hint` states the cause and the next step (for example, the image was not cached on the target node: retry, or pick a GPU type whose node already has the image), and `error.request_id` identifies the failure in the server log. |
19
21
  | `sandbox connect <id>` | Connect to an existing sandbox. |
20
22
  | `sandbox status <id>` | Check sandbox status (running / done). |
21
23
  | `sandbox finish <id> [--results '{...}']` | Save results and destroy the sandbox automatically. |
22
24
  | `sandbox kill <id>` | Destroy the sandbox immediately without saving results. |
25
+ | `sandbox extend <id> [--max-life N]` | Query or adjust the max lifetime of a running sandbox (N in minutes; omit `--max-life` to query the current lifecycle). `status` also reports the lifecycle summary under `data.lifecycle`. |
23
26
 
24
27
  ## Command execution
25
28
 
@@ -38,17 +41,27 @@
38
41
  | `sandbox working-directory <id>` | Get the sandbox's current working directory (absolute path `/workspace/{user_id}/{sandbox_id}`). |
39
42
  | `sandbox write <id> [--path <path>] --source <filename>` | Write a file (recommended). If `--path` is omitted, write to the working directory (`<working-directory>/<filename>`); a relative `--path` is also resolved under the working directory. An absolute `--path` is used as-is (but the `/workspace/<filename>` root path is outside the OSS sync scope and is not recommended). |
40
43
  | `sandbox write <id> --path <absolute-path> --data "..."` | Write a small amount of inline content (`--data` has no source filename, so `--path` must be specified explicitly). |
41
- | `sandbox write-multiple <id> --entry <src=path> [--entry ...]` | Write multiple files in one operation (a relative target `path` is also resolved under the working directory). |
44
+ | `sandbox write-multiple <id> --entry <remote-path>=<local-path> [--entry ...]` | Write multiple files in one operation (a relative target `path` is also resolved under the working directory). |
42
45
  | `sandbox pull <id> --source <sandbox-path> --target <local-path> [--recursive] [--pattern <glob>]` | Pull files/directories to the local machine (the reverse of `upload`; flag directions are reversed: `--source`=remote sandbox path, `--target`=local path). Single files are detected automatically; directories are traversed recursively by default; SHA-1 integrity is checked by both the CLI and server. |
46
+ | `sandbox upload <id> --source <local-directory> --target <sandbox-path>` | Upload a local directory (packaged as tar.gz, extracted server-side) and verify the resulting file list against the local manifest. `--source` is local, `--target` is inside the sandbox. |
43
47
  | `sandbox ls <id> --path <path>` | List directory contents (defaults to `.`). |
44
48
  | `sandbox stat <id> --path <path>` | Get file metadata (size / mode / owner / group). |
45
49
  | `sandbox mv <id> --entry <source=dest> [--entry ...]` | Move or rename files. |
46
50
  | `sandbox replace <id> --path <path> --old <text> --new <text> [--regex] [--ignore-case]` | Replace file contents. |
47
51
  | `sandbox chmod <id> --path <path> --mode <octal>` | Change file permissions. |
48
52
  | `sandbox rm <id> --path <path> [--path ...]` | Delete files. |
53
+ | `sandbox rmdir <id> --path <path> [--path ...]` | Delete directories recursively (cannot be undone). |
49
54
  | `sandbox mkdir <id> --path <path> [--path ...]` | Create directories (`mkdir -p`). |
50
55
  | `sandbox search <id> --path <root-directory> --pattern <glob>` | Search for files. |
51
56
 
57
+ ## Tunnelling (port exposure)
58
+
59
+ | Command | Description |
60
+ |------|------|
61
+ | `sandbox expose <id> [--port N]` | Expose a service port inside the sandbox to the public internet and return the `public_url` (the platform default inner port is 8700). |
62
+ | `sandbox exposes <id>` | List the public tunnels currently active for this sandbox. |
63
+ | `sandbox dispose <id> --port N` | Recycle one tunnel (stop frpc and release the public port); killing the sandbox also reclaims its tunnels. |
64
+
52
65
  ## Notes
53
66
 
54
67
  - `list` ≠ `ls`: `sandbox list` lists sandbox instances; `sandbox ls <id>` lists directories inside a sandbox.
@@ -7,7 +7,8 @@
7
7
  1. **Check available images** `delta-cli sandbox images` — list the images supported by the server. The image determines which language runtimes are available in the container (Python / Node.js / Go / Java / Rust, etc.); choose one that fits the user's technology stack and GPU/CPU requirements.
8
8
  2. **List existing sandboxes (optional)** `delta-cli sandbox list` — check the active sandboxes already created by the current user to avoid creating duplicates.
9
9
  3. **Create** `delta-cli sandbox create --image-name <image-name> --cpu 4 --memory 16Gi --gpu 1 --gpu-mem 8000 --max-life 120 [--gpu-type <model>] [--shm-size XGi] [--devices kvm]` (the sandbox is ready to use immediately; no connection step is needed. `--memory`/`--gpu-mem` accept g/m/G/M formats (for example, 1G/512M; lowercase is also accepted), which the CLI converts to Gi/Mi. `--max-life` sets the sandbox's maximum lifetime in minutes; the default is 30. `--no-auto-cleanup` prevents automatic cleanup; the sandbox can then be destroyed only with an explicit kill/finish. `--image-name` takes an image name, such as `"PyTorch CUDA13 (GPU)"`; compute backend selection is automatic and does not need to be specified. `--gpu-type` (optional) selects a GPU model, such as `"RTX 4090"` or `H100`; the server maps this to the HAMi use-gputype annotation for model-based scheduling. To see available models, check `sandbox resources` (the `third_party` group's `gpu_types[].gpu_name`); if omitted, scheduling is automatic. `--shm-size` (optional) increases the container's `/dev/shm` (the **default is only 64Mi**)—it must be increased when PyTorch `DataLoader(num_workers>0)`/`multiprocessing`, Chromium-based engines or similar report `No space left on device`/`Bus error`; **a Gi/Mi unit is required** (`4G`/`512M` are normalised by the CLI; the server rejects a bare number), and it **must not exceed `--memory`** (it is a memory filesystem and filling it causes OOMKill; `--memory` defaults to only 1Gi, so increasing shm usually requires increasing memory too, for example, `--memory 8Gi --shm-size 4Gi`). Only private compute (`private`) applies this setting (third-party compute ignores it), but unit/limit validation is backend-independent and rejects invalid values before creation. `--devices` (optional) requests host-device passthrough using comma-separated tokens (for example, `--devices kvm` makes `/dev/kvm` available inside the container for nested virtualisation); this raises privileges, and if the server allowlist is not enabled, creation is **explicitly rejected** (not silently ignored; validation is backend-independent). If this error occurs, do not retry; use an approach that does not depend on that device. Only private compute applies this setting. **Resource limits per sandbox**: cpu ≤ 512, memory ≤ 1024Gi, gpu ≤ 64, gpuMem ≤ 1024Gi, shmSize ≤ memory. Exceeding a limit returns a validation error promptly at request time rather than hanging.)
10
- 4. **Write code/data** `delta-cli sandbox write <id> --source <filename>` — write a local file directly to the sandbox. If `--path` is omitted, the file is written to that sandbox's working directory by default (`/workspace/{user_id}/{sandbox_id}/<filename>`, which is within the OSS sync scope, so the file persists after kill). Before writing, use `delta-cli sandbox working-directory <id>` to confirm the path. **You must** use a relative source path (for example, `--source infer.py`); do not use `"$WORKSPACE_ROOT/<filename>"` or `$(pwd)/...`. A relative `--path` is also resolved under the working directory; an absolute `--path` is used as-is (`/workspace/<filename>` is outside the OSS sync scope and is not recommended). You can also use `--data "..."` to write a small amount of inline content (requires an explicit `--path`), and `--mode 755` to set file permissions. The returned `size` field is the actual on-disk byte count verified with stat, so it can confirm that the write completed. Use `write-multiple` to write several files at once. File paths and extensions depend on the runtimes in the image.
10
+ - **If `create` fails**: the error envelope's `hint` states the cause and the next step. A common one is "the image may not be cached on the target node" — the initial pull exceeded the readiness timeout, so retry once (the pull continues in the background and later creates succeed) or pick a GPU type whose node already has the image. A failed create leaves no sandbox behind, so retrying is safe; `error.request_id` identifies the failure in the server log.
11
+ 4. **Write code/data** `delta-cli sandbox write <id> --source <filename>` — write a local file directly to the sandbox. If `--path` is omitted, the file is written to that sandbox's working directory by default (`/workspace/{user_id}/{sandbox_id}/<filename>`, which is within the OSS sync scope, so the file persists after kill). Before writing, use `delta-cli sandbox working-directory <id>` to confirm the path. **You must** use a relative source path (for example, `--source infer.py`); do not use `"$WORKSPACE_ROOT/<filename>"` or `$(pwd)/...`. A relative `--path` is also resolved under the working directory; an absolute `--path` is used as-is (the same rule applies to every sandbox-side path: the remote part of `write-multiple --entry`, `upload --target`, `pull --source`, and `run`/`run-bg --log-file`) (`/workspace/<filename>` is outside the OSS sync scope and is not recommended). You can also use `--data "..."` to write a small amount of inline content (requires an explicit `--path`), and `--mode 755` to set file permissions. The returned `size` field is the actual on-disk byte count verified with stat, so it can confirm that the write completed. Use `write-multiple` to write several files at once. File paths and extensions depend on the runtimes in the image.
11
12
  5. **Run a command** — first use `delta-cli sandbox working-directory <id>` to get `<wd>`, then construct a command for a runtime in the image. Common examples: `python <wd>/train.py` (Python), `node <wd>/app.js` (Node.js), `go run <wd>/main.go` (Go), `bash <wd>/run.sh` (Shell).
12
13
  - **Short tasks ≤60s**: `delta-cli sandbox run <id> --command "<command>" --timeout <seconds>` runs synchronously; raw SSE `data:` frames are passed through to stdout (with no trailing envelope), `exit_code`/`log_file` are read from the `complete` frame, and full stdout is written to the log_file.
13
14
  - **Long tasks >60s**: run `delta-cli sandbox run-bg <id> --command "<command>" --timeout <seconds> --wait` in the background (recommended), or use `run-bg` + `logs` for manual polling (`run-bg --wait` includes `--summary` by default; without `--wait`, it returns `{execution_id, sandbox_id}` immediately).
@@ -1,4 +1,10 @@
1
- # XRD Cloud Compute API Reference
1
+ # XRD reference
2
+
3
+ Make all online XRD calls with
4
+ `delta-cli science invoke --tool xrd --endpoint <operation>`.
5
+ Use the CLI's configured authentication and service address. Do not
6
+ call registry, gateway, or compute-service URLs directly, or follow returned
7
+ `content_url` and job `links` outside the CLI.
2
8
 
3
9
  The OpenAPI contract version is `1.2.0`. Business requests and responses use
4
10
  `schema_version: 1`.
@@ -8,110 +14,73 @@ sequences, refinement jobs, quality assessment, and error handling. Replace
8
14
  `art_<...>`, `<sha256>`, and `refjob_<...>` placeholders with values returned by
9
15
  the service in the same workflow.
10
16
 
11
- ## 1. Tool and endpoints
12
-
13
- The registered tool is `xrd`, tool ID `30`. The
14
- [tool record](http://8.141.101.94:8001/api/v1/tools/30) and
15
- [endpoint catalogue](http://8.141.101.94:8001/api/v1/tools/30/endpoints)
16
- identify 27 registered endpoints, all enabled. The catalogue server is a tool
17
- registry and invocation proxy; it is not the compute service base URL.
17
+ ## 1. Tool and operations
18
18
 
19
- Catalogue APIs, relative to `http://8.141.101.94:8001`:
20
-
21
- | Method and path | Purpose |
22
- | --- | --- |
23
- | `GET /api/v1/tools/30` | Tool identity and configuration |
24
- | `GET /api/v1/tools/30/endpoints` | All registered XRD endpoints |
25
- | `GET /api/v1/tools/30/endpoints?status=true` | Enabled XRD endpoints |
26
- | `GET /api/v1/tools/name/xrd/endpoints` | Endpoint lookup by tool name |
27
-
28
- Catalogue responses use `code`, `message`, and `data`; `code=0` indicates success.
29
- Endpoint records include `id`, `tool_id`, `name`, `path`, `method`, `price`,
30
- `featurekey`, and `status`. Registration and enabled status do not establish
31
- backend readiness. Recheck availability and prices before execution:
19
+ The CLI tool is `xrd`. Pass the operation names below exactly as `--endpoint`;
20
+ they are server catalogue contracts, not aliases. This table documents the
21
+ operations used by this reference, not a live inventory or price list.
22
+ When diagnosing availability, checking prices, or resolving a missing or
23
+ inconsistent contract, use CLI discovery:
32
24
 
33
25
  ```text
34
26
  delta-cli science list
35
27
  delta-cli science endpoints list xrd
36
28
  ```
37
29
 
38
- Use endpoint names exactly as registered. HTTP paths below are relative to the
39
- registered upstream compute service. Price values are the catalogue's `price`
40
- field; they do not specify a currency. All listed records have `status=true`.
41
-
42
- | Endpoint ID | CLI endpoint | HTTP method and path | Purpose / response | Price |
43
- | --- | --- | --- | --- | --- |
44
- | 128 | `healthz` | `GET /healthz` | Process liveness, JSON | 0 |
45
- | 129 | `readyz` | `GET /readyz` | Service readiness, JSON | 0 |
46
- | 130 | `capabilities` | `GET /v1/capabilities` | Components, versions, verification, modes, and limits | 0 |
47
- | 131 | `xqueryer-predictions` | `POST /v1/xqueryer/predictions` | Single-phase model predictions | 3 |
48
- | 132 | `xmatcher-detect-peaks` | `POST /v1/xmatcher/detect-peaks` | Observed peak detection | 4 |
49
- | 133 | `xmatcher-match` | `POST /v1/xmatcher/match` | Single-phase matching | 4 |
50
- | 134 | `xmatcher-multiphase-match` | `POST /v1/xmatcher/multiphase-match` | Multiphase candidate matching | 4 |
51
- | 135 | `xmatcher-cif-xrd` | `POST /v1/xmatcher/cif-xrd` | Theoretical XRD simulation from CIFs | 4 |
52
- | 136 | `xmatcher-pdf-peaks-xlsx` | `POST /v1/xmatcher/pdf-peaks-xlsx` | Theoretical peak tables, binary XLSX | 8 |
53
- | 137 | `xmatcher-status` | `GET /v1/xmatcher/status` | XMatcher database status | 0 |
54
- | 138 | `xdecomposer-predictions` | `POST /v1/xdecomposer/predictions` | Multiphase model decomposition | 2 |
55
- | 139 | `xmatcher-refinement-patterns` | `POST /v1/xmatcher/refinement-patterns` | Corrected pattern and provenance manifest | 0 |
56
- | 140 | `mp500-cif-exports` | `POST /v1/mp500/cif-exports` | Export a CIF by database identity | 0 |
57
- | 141 | `xmatcher-artifacts` | `POST /v1/artifacts` | Upload file bytes and return an artifact reference | 0 |
58
- | 143 | `xmatcher-artifact` | `GET /v1/artifacts/{artifact_id}` | Artifact metadata | 0 |
59
- | 144 | `xmatcher-artifact-content` | `GET /v1/artifacts/{artifact_id}/content` | Artifact content, binary | 0 |
60
- | 145 | `refinement-job` | `GET /v1/refinement-jobs/{job_id}` | Job status and results | 0 |
61
- | 146 | `refinement-job-cancel` | `POST /v1/refinement-jobs/{job_id}/cancel` | Request cancellation | 0 |
62
- | 147 | `refinement-job-events` | `GET /v1/refinement-jobs/{job_id}/events` | Paginated job events | 0 |
63
- | 148 | `refinement-job-artifacts` | `GET /v1/refinement-jobs/{job_id}/artifacts` | Public job artifacts | 0 |
64
- | 149 | `refinement-fullprof` | `POST /v1/refinement-jobs` | Submit a FullProf job, HTTP 202 | 15 |
65
- | 150 | `refinement-gsasii` | `POST /v1/refinement-jobs` | Submit a GSAS-II job, HTTP 202 | 12 |
66
- | 151 | `refinement-wpem` | `POST /v1/refinement-jobs` | Submit a PyXplore/WPEM job, HTTP 202 | 10 |
67
- | 160 | `simulation-cif-parse` | `POST /v1/simulation/cif-parse` | Parse CIF data blocks | 1 |
68
- | 161 | `simulation-cif-peaks` | `POST /v1/simulation/cif-peaks` | Simulate reflections for a selected block and wavelength | 1 |
69
- | 162 | `pdfreporter-analyses` | `POST /v1/pdfreporter/analyses` | Multiphase peak assignments and charts | 8 |
70
- | 163 | `pdfreporter-assignments` | `POST /v1/pdfreporter/analyses/assignments` | Recompute analysis with manual assignments | 8 |
71
-
72
- The three refinement CLI endpoints select backend and billing entries in the
73
- proxy. The compute service exposes one job submission route. HTTP `backends`
74
- values are `pyxplore`, `fullprof`, and `gsasii`; `refinement-wpem` corresponds to
75
- PyXplore/WPEM. Match the CLI endpoint and requested backends to the proxy configuration.
76
-
77
- ### Chemistry gateway
30
+ Registration and enabled status do not establish backend readiness. Do not add
31
+ catalogue or health calls to an ordinary workflow unless needed for the task.
78
32
 
79
- The Chemistry gateway prefix is `/api/v1/chem/xrd`. Allowed business routes are
80
- exposed as `/api/v1/chem/xrd/v1/...`. The gateway injects an upstream service token,
81
- rewrites `Location`, `content_url`, and job `links`, and preserves business HTTP
82
- status codes and download headers.
83
-
84
- - `GET /api/v1/chem/xrd/health` calls compute `/readyz`.
85
- This aggregate health endpoint uses the gateway's `BaseResponse` envelope.
86
- - The gateway allowlist excludes `/v1/xdecomposer/predictions`, both
87
- `/v1/simulation/...` routes, and both `/v1/pdfreporter/...` routes. Requests to
88
- these paths through this Chemistry gateway return 404. They are implemented by
89
- the compute service; access through other proxies depends on their configuration.
90
- - `/v1/identification/predictions`, `/v1/structures/cif-exports`, and
91
- `/v1/identification-jobs/...` appear in the gateway allowlist but have no
92
- corresponding routes in this compute service implementation.
33
+ | Operation (`--endpoint`) | Purpose / response |
34
+ | --- | --- |
35
+ | `healthz` | Process liveness, JSON |
36
+ | `readyz` | Service readiness, JSON |
37
+ | `capabilities` | Components, versions, verification, modes, and limits |
38
+ | `xqueryer-predictions` | Single-phase model predictions |
39
+ | `xmatcher-detect-peaks` | Observed peak detection |
40
+ | `xmatcher-match` | Single-phase matching |
41
+ | `xmatcher-multiphase-match` | Multiphase candidate matching |
42
+ | `xmatcher-cif-xrd` | Theoretical XRD simulation from CIFs |
43
+ | `xmatcher-pdf-peaks-xlsx` | Theoretical peak tables, binary XLSX |
44
+ | `xmatcher-status` | XMatcher database status |
45
+ | `xdecomposer-predictions` | Multiphase model decomposition |
46
+ | `xmatcher-refinement-patterns` | Corrected pattern and provenance manifest |
47
+ | `mp500-cif-exports` | Export a CIF by database identity |
48
+ | `xmatcher-artifacts` | Upload file bytes and return an artifact reference |
49
+ | `xmatcher-artifact` | Artifact metadata |
50
+ | `xmatcher-artifact-content` | Artifact content, binary |
51
+ | `refinement-job` | Job status and results |
52
+ | `refinement-job-cancel` | Request cancellation |
53
+ | `refinement-job-events` | Paginated job events |
54
+ | `refinement-job-artifacts` | Public job artifacts |
55
+ | `refinement-fullprof` | Submit a FullProf job |
56
+ | `refinement-gsasii` | Submit a GSAS-II job |
57
+ | `refinement-wpem` | Submit a PyXplore/WPEM job |
58
+ | `simulation-cif-parse` | Parse CIF data blocks |
59
+ | `simulation-cif-peaks` | Simulate reflections for a selected block and wavelength |
60
+ | `pdfreporter-analyses` | Multiphase peak assignments and charts |
61
+ | `pdfreporter-assignments` | Recompute analysis with manual assignments |
62
+
63
+ The refinement operations select backend and billing entries. Request `backends`
64
+ values are `pyxplore`, `fullprof`, and `gsasii`; `refinement-wpem` corresponds to
65
+ PyXplore/WPEM. Match the operation and requested backends to the catalogue contract.
93
66
 
94
67
  ## 2. Request conventions and CLI argument mapping
95
68
 
96
- Compute `/v1/...` endpoints require `Authorization: Bearer <token>`, except in
97
- explicitly configured isolated environments with authentication disabled.
98
- `/healthz` and `/readyz` have no Bearer dependency.
69
+ Pass business JSON through `--data`. For file uploads, pass local bytes through
70
+ `--file` and set `--content-type application/octet-stream`; uploads are not
71
+ multipart requests. Authentication is handled by the CLI, not business JSON or
72
+ manually supplied service tokens. Business request models reject unknown fields.
99
73
 
100
- JSON requests use `Content-Type: application/json`. File uploads use
101
- `Content-Type: application/octet-stream` with raw file bytes in the body.
102
- Uploads are not multipart requests.
74
+ An optional `X-Request-ID` in `--headers` accepts 1–128 characters from letters,
75
+ digits, and `._:-`. Preserve the returned request ID for diagnostics.
103
76
 
104
- The optional `X-Request-ID` header accepts 1–128 characters from letters, digits,
105
- and `._:-`. Responses also return this header. Business request models reject
106
- unknown fields.
107
-
108
- | CLI argument | Upstream meaning |
77
+ | CLI argument | Meaning for XRD calls |
109
78
  | --- | --- |
110
79
  | `--data` | JSON request body |
111
80
  | `--params` | URL query parameters, including upload metadata and event pagination |
112
- | `--path-params` | Replace `{artifact_id}` and `{job_id}` in paths |
81
+ | `--path-params` | Artifact or job identity: `artifact_id` or `job_id` |
113
82
  | `--headers` | Additional headers, such as `Idempotency-Key` and `X-Content-SHA256` |
114
- | `--file` | Upload a local file through the tool proxy |
83
+ | `--file` | Upload a local file through the CLI |
115
84
  | `--content-type` | Upload body Content-Type; use `application/octet-stream` |
116
85
 
117
86
  `--params` cannot replace `--path-params`. Keep local paths, base64 content, and
@@ -119,17 +88,23 @@ idempotency keys out of business JSON. Use `science invoke --file` for XRD uploa
119
88
  The `media_type` query parameter describes the stored file format separately
120
89
  from the upload body Content-Type.
121
90
 
122
- The registry proxy exposes `POST /api/v1/tools/invoke` with required
123
- `tool_name` and `endpoint_name` fields. Optional fields are `data`, `params`,
124
- `path_params`, `headers`, `file_base64`, and `content_type`. A supplied
125
- file_base64 is decoded and forwarded as raw bytes, taking precedence over data;
126
- content_type defaults to application/octet-stream. Delta CLI maps its invocation
127
- arguments to these proxy fields. Tool ID 30 is used for catalogue lookup;
128
- invocation selects `tool_name="xrd"` and a registered endpoint name.
91
+ All operations in this reference, including uploads, binary responses, and XRD
92
+ refinement jobs, use `science invoke`. The `science file` and `science task`
93
+ adapters documented for QE/Materials Design do not replace these XRD operations.
94
+
95
+ ```text
96
+ delta-cli science invoke --tool xrd --endpoint <operation> `
97
+ [--data JSON] [--params JSON] [--path-params JSON] [--headers JSON]
98
+ ```
99
+
100
+ Pass each JSON object as one safely quoted argument. The examples below use
101
+ PowerShell continuation syntax. A call succeeds only when the CLI exits with
102
+ code 0 and its top-level JSON has `ok:true`; read business fields from `data`.
129
103
 
130
104
  ## 3. Call sequence
131
105
 
132
- 1. Inspect the CLI catalogue and check readiness and required capabilities.
106
+ 1. Select the documented operation; inspect the CLI catalogue, readiness, or
107
+ required capabilities only when the task or diagnosis requires it.
133
108
  2. Upload observed patterns, model inputs, CIFs, or instrument files. Save the
134
109
  returned `artifact_id` and `sha256` together.
135
110
  3. Use XMatcher or XDecomposer for observed data. XQueryer requires a prepared
@@ -149,13 +124,17 @@ invocation selects `tool_name="xrd"` and a registered endpoint name.
149
124
  delta-cli science invoke --tool xrd --endpoint healthz
150
125
  delta-cli science invoke --tool xrd --endpoint readyz
151
126
  delta-cli science invoke --tool xrd --endpoint capabilities
127
+ delta-cli science invoke --tool xrd --endpoint xmatcher-status
152
128
  ```
153
129
 
154
- `GET /healthz` returns `200 {"ok":true}` for process liveness.
155
- `GET /readyz` checks authentication configuration and required components;
156
- an unready service returns `503 {"ok":false}`.
130
+ `healthz` returns business `{"ok":true}` for process liveness.
131
+ `readyz` checks authentication configuration and required components;
132
+ an unready service fails the call. Keep probe business `ok` distinct from the
133
+ CLI envelope's top-level `ok`.
157
134
 
158
- `GET /v1/capabilities` returns `components.<name>.available`, component `details`,
135
+ `xmatcher-status` queries XMatcher database status without a request body.
136
+
137
+ `capabilities` returns `components.<name>.available`, component `details`,
159
138
  `limits`, and build information. Check the components required for the workflow,
160
139
  checksums, asset release approval, and mode availability. Report GPU use only when
161
140
  the returned device or backend explicitly supports that conclusion.
@@ -176,16 +155,17 @@ described in its detailed contract; consult the deployed capability for its limi
176
155
 
177
156
  ### Upload
178
157
 
179
- `POST /v1/artifacts` returns HTTP 201, an `ArtifactRef`, and a metadata query
180
- URL in the `Location` header.
158
+ Operation: `xmatcher-artifacts`. Pass the local file with `--file`; read the
159
+ returned `ArtifactRef` from CLI `data`. Query its identity with
160
+ `xmatcher-artifact` and `--path-params`, rather than a returned URL.
181
161
 
182
- | Parameter | Location | Requirement |
162
+ | Parameter | CLI argument | Requirement |
183
163
  | --- | --- | --- |
184
- | `filename` | Query | Required; 1–255 characters; no `/` or `\` |
185
- | `kind` | Query | Required; accepted kinds are listed below |
186
- | `media_type` | Query | Required; 1–255 characters; no line breaks |
187
- | `preserve_source` | Query | Default false; preserve original observed text pattern bytes |
188
- | `X-Content-SHA256` | Header | Optional; 64 lowercase hexadecimal characters, hashing the upload bytes |
164
+ | `filename` | `--params` | Required; 1–255 characters; no `/` or `\` |
165
+ | `kind` | `--params` | Required; accepted kinds are listed below |
166
+ | `media_type` | `--params` | Required; 1–255 characters; no line breaks |
167
+ | `preserve_source` | `--params` | Default false; preserve original observed text pattern bytes |
168
+ | `X-Content-SHA256` | `--headers` | Optional; 64 lowercase hexadecimal characters, hashing the upload bytes |
189
169
 
190
170
  | Accepted upload kind | File and processing rules |
191
171
  | --- | --- |
@@ -239,14 +219,15 @@ delta-cli science invoke --tool xrd --endpoint xmatcher-artifact-content `
239
219
  --path-params '{"artifact_id":"art_<returned-id>"}'
240
220
  ```
241
221
 
242
- The HTTP content response contains file bytes with `ETag` and
243
- `X-Artifact-SHA256` headers. A CLI proxy may wrap binary data with `data._binary`,
244
- `content_base64`, `media_type`, and `content_length`. Verify saved content against
245
- the returned SHA-256, and determine its format from the media type and content.
222
+ Read binary content from the documented CLI response fields. The tool proxy may
223
+ wrap it as `data._binary`, `data.content_base64`, `data.media_type`, and
224
+ `data.content_length`. Decode `content_base64` only when the response declares
225
+ that representation. Verify saved content against the artifact's returned
226
+ SHA-256, and determine its format from the media type and content.
246
227
 
247
228
  ## 6. Phase identification and matching
248
229
 
249
- ### XQueryer: `POST /v1/xqueryer/predictions`
230
+ ### XQueryer: `xqueryer-predictions`
250
231
 
251
232
  `pattern` must reference a `model_input_pattern` containing exactly 3,500 points
252
233
  on a uniform 10–90° 2theta grid. Maximum grid error is `1e-6`. Intensities must be
@@ -270,7 +251,7 @@ softmax probability.
270
251
 
271
252
  ### Peak detection and single-phase XMatcher
272
253
 
273
- `POST /v1/xmatcher/detect-peaks` accepts `schema_version`, `pattern`, `params`,
254
+ `xmatcher-detect-peaks` accepts `schema_version`, `pattern`, `params`,
274
255
  and optional `expected_xmatcher_database_sha256`. XMatcher accepts
275
256
  `observed_pattern` or `model_input_pattern` artifacts.
276
257
 
@@ -293,7 +274,7 @@ peak_match_score values and include calibration_adjusted_score. Interpret ranks
293
274
  using `ranking` and `effective_settings`. Learned mode explicitly reports
294
275
  `score_is_probability=false`; do not average these scores with XQueryer probabilities.
295
276
 
296
- ### Multiphase XMatcher: `POST /v1/xmatcher/multiphase-match`
277
+ ### Multiphase XMatcher: `xmatcher-multiphase-match`
297
278
 
298
279
  ```text
299
280
  delta-cli science invoke --tool xrd --endpoint xmatcher-multiphase-match `
@@ -337,7 +318,7 @@ effective settings.
337
318
  | `multiphase_missing_peak_weight` / `multiphase_phase_penalty` | 0.5 / 3.0 | ≥0 |
338
319
  | `multiphase_minimum_phase_contribution_percent` | 8.0 | [0,100) |
339
320
 
340
- ### XDecomposer: `POST /v1/xdecomposer/predictions`
321
+ ### XDecomposer: `xdecomposer-predictions`
341
322
 
342
323
  ```text
343
324
  delta-cli science invoke --tool xrd --endpoint xdecomposer-predictions `
@@ -354,7 +335,7 @@ map them to unique indices in 1–3 when constructing refinement requests.
354
335
 
355
336
  ### XMatcher simulation and XLSX export
356
337
 
357
- `POST /v1/xmatcher/cif-xrd` and `/v1/xmatcher/pdf-peaks-xlsx` share a request model.
338
+ Operations: `xmatcher-cif-xrd` and `xmatcher-pdf-peaks-xlsx`; they share a request model.
358
339
 
359
340
  ```text
360
341
  delta-cli science invoke --tool xrd --endpoint xmatcher-cif-xrd `
@@ -365,14 +346,16 @@ delta-cli science invoke --tool xrd --endpoint xmatcher-cif-xrd `
365
346
  nonnegative weight defaulting to 1. `two_theta_range` must be finite and
366
347
  increasing. `min_intensity` defaults to 0 and must be nonnegative; fwhm and step
367
348
  must be positive. `wavelength` is a string, separate from the numeric `lambda`
368
- field in the simulation API below. `expected_xmatcher_database_sha256` is optional.
349
+ field in `simulation-cif-peaks` below. `expected_xmatcher_database_sha256` is optional.
369
350
 
370
- The peak-table endpoint returns XLSX bytes with media type
371
- `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`.
351
+ For peak-table export, use the same `--data` shape with
352
+ `--endpoint xmatcher-pdf-peaks-xlsx`. The response contains XLSX bytes with media
353
+ type `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`; decode
354
+ the CLI binary response as described in section 5.
372
355
 
373
356
  ### MP500, RRUFF, and OPXRD CIF export
374
357
 
375
- `POST /v1/mp500/cif-exports` requires both the candidate entry_id and its identity:
358
+ Operation: `mp500-cif-exports`. It requires both the candidate entry_id and its identity:
376
359
 
377
360
  ```text
378
361
  delta-cli science invoke --tool xrd --endpoint mp500-cif-exports `
@@ -391,7 +374,7 @@ MP500 or RRUFF mismatch errors; do not substitute guessed identifiers.
391
374
 
392
375
  ### CIF block parsing and reflection simulation
393
376
 
394
- CLI endpoint: `simulation-cif-parse`. Request for `POST /v1/simulation/cif-parse`:
377
+ Operation: `simulation-cif-parse`. Pass this request through `--data`:
395
378
 
396
379
  ```json
397
380
  {"schema_version":1,"cif":{"artifact_id":"art_<cif>","sha256":"<sha256>"}}
@@ -404,10 +387,10 @@ delta-cli science invoke --tool xrd --endpoint simulation-cif-parse `
404
387
 
405
388
  The response contains `blocks[]`. Successful blocks include block_index,
406
389
  block_name, formula, cell, volume, site_count, spacegroup, and warnings. Failed
407
- blocks include block_index and error. Inspect individual blocks even when HTTP
408
- status is 200.
390
+ blocks include block_index and error. Inspect individual blocks even when the
391
+ CLI invocation succeeds.
409
392
 
410
- CLI endpoint: `simulation-cif-peaks`. Request for `POST /v1/simulation/cif-peaks`:
393
+ Operation: `simulation-cif-peaks`. Pass this request through `--data`:
411
394
 
412
395
  ```json
413
396
  {"schema_version":1,"cif":{"artifact_id":"art_<cif>","sha256":"<sha256>"},"block":0,"lambda":1.5406,"min_angle":5.0,"max_angle":90.0}
@@ -427,7 +410,7 @@ Neither simulation endpoint depends on XMatcher search assets.
427
410
 
428
411
  ## 8. PDF Reporter peak assignments
429
412
 
430
- CLI endpoint: `pdfreporter-analyses`. Request for `POST /v1/pdfreporter/analyses`:
413
+ Operation: `pdfreporter-analyses`. Pass this request through `--data`:
431
414
 
432
415
  ```json
433
416
  {
@@ -462,9 +445,8 @@ The response includes per-phase theory tables in `phases`, flattened theory in
462
445
  rasterization dependencies are unavailable.
463
446
  Peak statuses are `unmatched`, `unique`, `ambiguous`, and `manual`.
464
447
 
465
- CLI endpoint: `pdfreporter-assignments`. For
466
- `POST /v1/pdfreporter/analyses/assignments`, resubmit the complete analysis input
467
- and add this field:
448
+ Operation: `pdfreporter-assignments`. Resubmit the complete analysis input through
449
+ `--data` and add this field:
468
450
 
469
451
  ```json
470
452
  {"selections":{"38.45|0":"0:0","30.05|0":"none"}}
@@ -500,7 +482,11 @@ processing settings, not additional request fields.
500
482
 
501
483
  ### Basic job submission
502
484
 
503
- `POST /v1/refinement-jobs` requires `Idempotency-Key` with 8–200 characters:
485
+ Operations: `refinement-fullprof`, `refinement-gsasii`, or `refinement-wpem`.
486
+ Pass `Idempotency-Key` through `--headers`, with 8–200 characters. The example
487
+ submits GSAS-II; select the corresponding operation and explicit `backends`
488
+ value for FullProf or PyXplore. Submission and cancellation require the user's
489
+ authorisation for that action.
504
490
 
505
491
  ```text
506
492
  delta-cli science invoke --tool xrd --endpoint refinement-gsasii `
@@ -568,24 +554,20 @@ in `summary.wpem_evidence`.
568
554
  preserve_source=true. This mode prohibits corrected_pattern,
569
555
  provenance_manifest, and basic-mode cycles/refine switches.
570
556
 
571
- Request for `POST /v1/refinement-jobs`, with an idempotency header:
557
+ Submit with `--endpoint refinement-gsasii`, business JSON in `--data`, and the
558
+ idempotency key in `--headers`:
572
559
 
573
- ```json
574
- {
575
- "schema_version":1,
576
- "radiation_profile":"CuKa",
577
- "refinement_pattern":{"observed_pattern":{"artifact_id":"art_<original>","sha256":"<sha256>"}},
578
- "phases":[{"phase_index":1,"name":"phase","cif":{"artifact_id":"art_<cif>","sha256":"<sha256>"}}],
579
- "wavelengths_angstrom":[1.540593,1.544414],
580
- "backends":["gsasii"],
581
- "options":{"timeout_seconds":900,"gsasii":{"workflow_mode":"gsas-report-initial-v1"}}
582
- }
560
+ ```text
561
+ delta-cli science invoke --tool xrd --endpoint refinement-gsasii `
562
+ --data '{"schema_version":1,"radiation_profile":"CuKa","refinement_pattern":{"observed_pattern":{"artifact_id":"art_<original>","sha256":"<sha256>"}},"phases":[{"phase_index":1,"name":"phase","cif":{"artifact_id":"art_<cif>","sha256":"<sha256>"}}],"wavelengths_angstrom":[1.540593,1.544414],"backends":["gsasii"],"options":{"timeout_seconds":900,"gsasii":{"workflow_mode":"gsas-report-initial-v1"}}}' `
563
+ --headers '{"Idempotency-Key":"<stable-unique-key>"}'
583
564
  ```
584
565
 
585
566
  Optional `recipe` controls single-phase baseline/candidates, multiphase baseline,
586
567
  physical bounds, selection rules, and residual peak definitions. Omission uses
587
- the backend default recipe. Complete recipe types are defined in OpenAPI and
588
- the GSAS reference. The official scoring implementation is pinned by version
568
+ the backend default recipe. Only supply a custom recipe when the current
569
+ service schema defines its fields; do not guess nested recipe fields.
570
+ The official scoring implementation is pinned by version
589
571
  and module SHA-256; callers cannot replace it.
590
572
 
591
573
  Report mode accepts a finite nonnegative `ka2_ka1_intensity_ratio` for doublets.
@@ -608,12 +590,13 @@ establish calibration.
608
590
 
609
591
  ### Acceptance, queries, and cancellation
610
592
 
611
- Successful submission returns HTTP 202 with schema_version, job_id,
612
- status=queued, submitted_at, and links.self/events/artifacts. Location points
613
- to the job query route.
593
+ Successful submission returns business `schema_version`, `job_id`,
594
+ `status=queued`, `submitted_at`, and `links.self/events/artifacts` in CLI `data`.
595
+ This means accepted/queued, not convergence or scientific acceptance. Use the
596
+ returned `job_id` with CLI query operations; do not follow the link URLs directly.
614
597
 
615
598
  The same idempotency key and canonical request reuse the original job.
616
- The same key with a different request returns 409 IDEMPOTENCY_CONFLICT.
599
+ The same key with a different request returns IDEMPOTENCY_CONFLICT.
617
600
  Use a new key for an intentional new calculation. After a timeout or disconnect,
618
601
  retain the original key and investigate whether a job exists before resubmitting.
619
602
 
@@ -635,7 +618,8 @@ delta-cli science invoke --tool xrd --endpoint refinement-job-cancel `
635
618
  Job IDs contain `refjob_` followed by 32 lowercase hexadecimal characters.
636
619
  Event after_seq defaults to 0 and must be nonnegative; limit defaults to 100
637
620
  and accepts 1–500. Pass response next_after_seq for the next page.
638
- Artifact lists are deduplicated by artifact_id; download through the content API.
621
+ Artifact lists are deduplicated by artifact_id; download through
622
+ `xmatcher-artifact-content` with `--path-params '{"artifact_id":"art_<returned-id>"}'`.
639
623
 
640
624
  Cancellation returns the job's current state. Continue querying until a terminal
641
625
  state is reached. Cancelling completed or failed jobs returns JOB_STATE_CONFLICT.
@@ -653,14 +637,14 @@ validity, or scientific acceptance. Preserve null or unknown values for unavaila
653
637
 
654
638
  ## 10. Responses and errors
655
639
 
656
- Compute endpoints generally return business JSON directly, without a common
657
- top-level `ok` or `data` success envelope. Health probes, CLI responses, and
658
- gateway aggregate health endpoints each use their own response conventions.
640
+ A successful Delta CLI invocation requires exit code 0 and top-level `ok:true`;
641
+ business results are in `data`. XRD business JSON generally has no additional
642
+ common `ok`/`data` envelope. Read the fields documented for the selected operation;
643
+ health probes have their own business `ok`. Decode binary responses using the
644
+ CLI representation and returned media type described in section 5.
659
645
 
660
- A successful Delta CLI invocation requires exit code 0 and top-level ok=true;
661
- business results are in data. Decode binary responses according to Content-Type.
662
-
663
- Compute error response:
646
+ The CLI reports failures in its top-level `error`. Native business-error details,
647
+ when exposed by the CLI, may have this shape:
664
648
 
665
649
  ```json
666
650
  {
@@ -670,7 +654,9 @@ Compute error response:
670
654
  }
671
655
  ```
672
656
 
673
- Gateway-generated errors include error and request_id but may omit schema_version.
657
+ Gateway-generated business errors may omit schema_version. Preserve the CLI's
658
+ error classification and any returned native details; do not infer success from
659
+ a nested field or bypass the CLI to retrieve an upstream response.
674
660
 
675
661
  | Common error | Meaning / action |
676
662
  | --- | --- |
@@ -683,22 +669,20 @@ Gateway-generated errors include error and request_id but may omit schema_versio
683
669
  | REFINEMENT_LINEAGE_INVALID / INSTRUMENT_INVALID | Invalid provenance, source preservation, or instrument data |
684
670
  | IDEMPOTENCY_CONFLICT / JOB_NOT_FOUND / JOB_STATE_CONFLICT | Conflicting key, missing job, or operation incompatible with job state |
685
671
  | REDIS_UNAVAILABLE / XMATCHER_TIMEOUT | Queue unavailable or matching wait timeout |
686
- | UPSTREAM_UNAVAILABLE / NOT_FOUND | Chemistry gateway connection failure or route not exposed |
672
+ | UPSTREAM_UNAVAILABLE / NOT_FOUND | Upstream unavailable or operation not exposed; report the original CLI error |
687
673
 
688
- HTTP 429 responses may include Retry-After. Proxy errors such as Endpoint is
674
+ Rate-limit failures may include Retry-After. Proxy errors such as Endpoint is
689
675
  disabled and TIER_CONCURRENCY_EXCEEDED are separate from native compute errors.
690
676
  Preserve returned code, message, details, warnings, and request_id. Do not switch
691
677
  endpoints, guess parameters, or replace failed business results with local algorithms.
692
678
 
693
- ## 11. Contracts and references
694
-
695
- - [Registered XRD tool](http://8.141.101.94:8001/api/v1/tools/30)
696
- - [Registered XRD endpoint catalogue](http://8.141.101.94:8001/api/v1/tools/30/endpoints)
697
- - [Registry proxy OpenAPI](http://8.141.101.94:8001/openapi.json)
698
- - [Compute OpenAPI](xrd-cloud-compute-handoff/contracts/openapi.yaml)
699
- - [Compute routes](xrd-cloud-compute-handoff/src/xrd_cloud_compute/api.py)
700
- - [Compute request and response models](xrd-cloud-compute-handoff/src/xrd_cloud_compute/models.py)
701
- - [Compute runtime and input validation](xrd-cloud-compute-handoff/src/xrd_cloud_compute/runtime.py)
702
- - [Chemistry gateway allowlist](delta-sandbox-server/api_server/api/chem_xrd.py) and [forwarding implementation](delta-sandbox-server/api_server/server/xrd_service_client.py)
703
- - [GSAS-II reference](xrd-cloud-compute-handoff/docs/GSASII_REFINEMENT_API_20261012.md)
704
- - [PyXplore reference](xrd-cloud-compute-handoff/docs/PYXPLORE_API_20261010.md)
679
+ ## 11. Contract discovery
680
+
681
+ Use `delta-cli science endpoints list xrd` when this reference is missing an
682
+ operation or conflicts with the deployed catalogue. Use only exact returned
683
+ names. If the catalogue does not provide enough schema to construct a request,
684
+ report the missing contract rather than guessing parameters or service paths.
685
+
686
+ See [Delta Science](../SKILL.md) for shared CLI authentication, response,
687
+ retry, and cross-tool rules. The direct `gsasii` tool is a separate contract;
688
+ its operation names must not be substituted for `xrd` refinement operations.
@@ -71,13 +71,14 @@ This returns the current user's information and remaining credits (through the g
71
71
 
72
72
  ```json
73
73
  {"ok":true,"data":{...}}
74
- {"ok":false,"error":{"type":"auth","message":"...","hint":"..."}}
74
+ {"ok":false,"error":{"type":"auth","message":"...","hint":"...","request_id":"..."}}
75
75
  ```
76
76
 
77
77
  AI agent parsing rules:
78
78
  - Always check `ok`; do not rely on the exit code alone.
79
79
  - `error.type` is the stable field for branching on: `auth`, `permission`, `not_found`, `validation`, `network`, `api`, `command_failed`, `internal`.
80
- - `error.hint` may be shown to the user.
80
+ - `error.hint` may be shown to the user. **Act on it rather than retrying blindly**: for a failed `sandbox create` the hint names the concrete cause and the next step (for example, the image was not cached on the target node — retry, or pick a GPU type whose node already has the image).
81
+ - `error.request_id` identifies the same failure in the server log; quote it when reporting the failure.
81
82
 
82
83
  ## Exit code conventions
83
84
 
@@ -110,4 +111,5 @@ delta-cli upgrade
110
111
  | `error.type: network` | Check `base_url` and network connectivity |
111
112
  | `error.type: validation` | Check required flags and argument formats |
112
113
  | `error.type: command_failed` | Command failed inside the sandbox: the envelope's `message` already includes the stderr tail to help locate the issue quickly; the full `stderr` / `result_summary` are in the `complete` frame. Retry or correct the command |
114
+ | `sandbox create` failed (`error.type: api` with a specific `hint`) | Follow the hint — it names the cause and the next step. "the image may not be cached on the target node" → retry once (the pull continues in the background, so later creates succeed) or pick a GPU type whose node already has the image. "check the target node's free disk space" → a retry will not help until an operator frees the node. A failed create leaves no sandbox behind, so retrying is safe. Quote `error.request_id` when reporting it. |
113
115
  | Configuration file parsing failed | Check that `~/.delta-infra/config.json` contains valid JSON |