A node's worker label is worker, so a device is only a paired one

- NodeDef `device`/`device_policy` become `worker`/`worker_policy`, the
  issue `ignored_device` becomes `ignored_worker`, and the SDK's `@node`
  takes `worker=` and `worker_policy=`
- FlowStore._migrate renames the keys in published and draft documents
  once, bumping their version; a queued run's `needs` reads the old key
- placement passes the label as `label`, client regenerated
- docs: worker placement wording, MCP issuer without DOMAIN, device rows in
  the CLI data directory and the API table, device links in compose comments

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Melvin Strobl
2026-10-16 16:56:05 +02:00
co-authored by Claude Opus 5.5
parent f8011d2a8a
commit a9d453c9d9
40 changed files with 215 additions and 178 deletions
+4 -4
View File
@@ -24,8 +24,8 @@ def train_curve(lr: float, epochs: int) -> list[float]:
Port("weights", "artifact"),
Port("final_loss", "float"),
],
device="gpu",
device_policy="prefer",
worker="gpu",
worker_policy="prefer",
timeout=600,
resources={"cpus": 2},
)
@@ -34,8 +34,8 @@ def fit(dataset, lr, epochs=25):
Yielding is the reporting: each one publishes on the `loss` port the
instant it happens, and the run keeps every value as a series — which is
why there is no `log_metric()` to call. `device="gpu"` with
`device_policy="prefer"` sends this to a worker carrying that label when
why there is no `log_metric()` to call. `worker="gpu"` with
`worker_policy="prefer"` sends this to a worker carrying that label when
one is attached, and runs it here when none is.
`resources` is what a real training node needs and the rest of a flow does