Keep a flow's runs when the flow goes
A run record is a record of what ran, so deleting a flow no longer sweeps its
history: `_forget_runs` is gone from the flow-delete path, and `DELETE /runs/{id}`
is the only thing that removes a run one at a time. The in-flight guard stays —
that is about work, not history.
`DELETE /runs?flow=` is the counterpart to the list's flow filter and what a
reseed needs, sharing the four statements with the single-run delete and
refusing the same way while a run of that flow is still going.
A run whose flow is gone reads as one: `useFlowInputs` reports the 404 rather
than an empty declaration set, so the run page says "flow deleted", explains it,
and disables Retry, which the route would refuse anyway.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CL9zvnnvcp1mvA8o7impxk
This commit is contained in:
+3
-1
@@ -46,7 +46,7 @@ Agents authenticate differently; see [Agents over MCP](agents.md).
|
||||
| `POST` | `/flows/{name}/publish` | put the draft live |
|
||||
| `POST` | `/flows/{name}/discard-draft` | throw the draft away |
|
||||
| `POST` | `/flows/{name}/rename` | rename it |
|
||||
| `DELETE` | `/flows/{name}` | delete it |
|
||||
| `DELETE` | `/flows/{name}` | delete it. Its runs stay — a run is the record of what ran, and only `DELETE /runs` clears one. Refused with 409 while a run of it is `running` or `queued` |
|
||||
| `GET` | `/flows/node-types` | every node type and its parameter schema |
|
||||
| `GET` | `/flows/graph` | every flow as one graph — what Home draws |
|
||||
|
||||
@@ -104,12 +104,14 @@ published to. Flows own the namespace; everything else is a client of it.
|
||||
| `POST` | `/runs/flows/{name}` | queue one run — `{"params": {...}, "seed": 7, "draft": false, "no_cache": false}`. `"cause"` says where it came from — `api` (the default), `cli` or `sdk` |
|
||||
| `POST` | `/runs/flows/{name}/sweep` | queue many, sharing a `group_id` |
|
||||
| `GET` | `/runs` | the queryable history: `?flow=`, `?status=`, `?group=`, `?digest=`, `?since=`, `?before=`, `?limit=`, `?offset=` |
|
||||
| `DELETE` | `/runs?flow=` | every run of one flow, and everything hanging off them. `flow` is required. Refused with 409 while one of them is still going |
|
||||
| `GET` | `/runs/overview` | one row per flow that has runs, with how many are running or queued |
|
||||
| `GET` | `/runs/export/metrics?…&name=&stride=&format=` | every selected run's series as one long table: `run, name, step, ts, value` |
|
||||
| `GET` | `/runs/export/runs?…¶ms=&metrics=&format=` | one row per run: its inputs as columns, its final numbers, its status and provenance |
|
||||
| `GET` | `/runs/metrics/names?…` | every metric name the selected runs recorded, distinct; takes the export's own filters |
|
||||
| `GET` | `/runs/{id}` | one run in full: params, result, per-node record, artifacts |
|
||||
| `POST` | `/runs/{id}/cancel` | stop it |
|
||||
| `DELETE` | `/runs/{id}` | forget it, with its nodes, series and artifact rows. Cancel a live one first |
|
||||
| `POST` | `/runs/{id}/retry` | run the same thing again, as a new run naming this one |
|
||||
| `GET` | `/runs/{id}/metrics?name=&stride=` | one metric's series, in step order; every series of the run without `name` |
|
||||
| `GET` | `/runs/series/compare?ids=a,b,c&metric=&x=` | that metric across several runs. `x` is what to plot against: nothing or `step`, `time` (seconds since each run's own first reading), or another metric's name, joined on the step the two share |
|
||||
|
||||
+13
-5
@@ -233,8 +233,9 @@ execution that is not happening this time, so its series is not rewritten
|
||||
either. The run it was restored from is recorded instead, and that is where the
|
||||
curve is read back from: asking the reusing run for its metrics answers with
|
||||
the same points, under its own flow's names. The one way to be left with a
|
||||
result and no curve is for that earlier run to have been deleted, which
|
||||
deleting its flow does.
|
||||
result and no curve is for that earlier run to have been deleted. Deleting a
|
||||
flow does not do that — its runs stay — so this only happens when the run
|
||||
itself was deleted.
|
||||
|
||||
## Objects that cannot be serialized
|
||||
|
||||
@@ -346,6 +347,14 @@ the artifacts it made, its metrics and its result. **Retry** submits it again
|
||||
as a run of its own, keeping the flow, the inputs, the seed and the sweep it
|
||||
belonged to.
|
||||
|
||||
A run outlives the flow it ran. Deleting a flow leaves its history standing —
|
||||
being the record of what ran is the point of keeping one — so the Runs screen
|
||||
still lists it, and opening it says **flow deleted** with Retry disabled,
|
||||
because there is nothing left to run it against. Clearing that history is a
|
||||
decision of its own: a run at a time on the screen, or
|
||||
`DELETE /api/v1/runs?flow=<name>` for a whole flow's worth, which is what a
|
||||
reseed wants.
|
||||
|
||||
### Taking it into a dataframe
|
||||
|
||||
An analysis wants a table rather than a screen, and there are two it usually
|
||||
@@ -407,9 +416,8 @@ sweep, or specific runs. It re-reads on its own and whenever a run finishes.
|
||||
### When a run draws nothing
|
||||
|
||||
A node restored from the [stage cache](#stage-caching) has its curve read back
|
||||
from the run that recorded it. Delete that run, which deleting its flow does,
|
||||
and the reusing run is left with a result and an empty curve, and the chart says so
|
||||
rather than looking broken.
|
||||
from the run that recorded it. Delete that run and the reusing run is left with
|
||||
a result and an empty curve, and the chart says so rather than looking broken.
|
||||
|
||||
## What this costs, compared
|
||||
|
||||
|
||||
Reference in New Issue
Block a user