Add POST /runs/import for runs executed elsewhere

A history recorded before the move (MLflow experiments) had nowhere to
go, since runs were only made by running a flow. Each entry is stored as
it ended: parameters completed and checked like a submit, cause
"import", empty commit and code digest, metrics and artifacts written
as given, nothing queued or announced. Run.external_id (new migration)
makes a second import a no-op and is an export column so a row joins
back. The request is all or nothing and capped at 200 entries;
Client.import_runs pages a longer history.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QgG6TJw5qBZzaLghQSRVrq
This commit is contained in:
2026-09-16 17:01:07 +02:00
co-authored by Claude Opus 5
parent eeaa46d4ae
commit d9630f66f5
12 changed files with 848 additions and 32 deletions
+11
View File
@@ -103,6 +103,7 @@ 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` |
| `POST` | `/runs/import` | record runs executed somewhere else, up to 200 per request. Answers `[{"external_id", "id", "created"}]` |
| `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 |
@@ -120,6 +121,16 @@ Submitting answers immediately with a `queued` run. Wrong parameters (an
undeclared name, a value of the wrong type) come back as a 422 naming the
problem, before anything executes.
`/runs/import` takes `{"runs": [...]}`. Each entry carries `flow`,
`external_id`, `params`, `seed`, `status` (`ok`, `error` or `cancelled`),
`created_at`, `started_at`, `finished_at`, `result`, `metrics` (`name`,
`step`, `ts`, `value`), `artifacts` (`name`, `filename`, `media_type`,
`content_base64`), `labels` and `group_id`. The parameters are completed and
checked as a submit's are, the run is stored with the cause `import` and an
empty commit and code digest, and nothing is queued. The request is checked
whole before anything is written, and an `external_id` already imported
answers with that run and `"created": false`.
`?digest=` filters by the hash of the parameters, which is how you find "every
run that used exactly this configuration".