Skip to main content

Module tasks

Module tasks 

Source
Expand description

HTTP surface for the Task/Run persistence axis (issue #13 ID hierarchy; GET /v1/tasks, GET /v1/tasks/:id, POST /v1/tasks/:id/runs, GET /v1/runs/:id). POST /v1/tasks itself stays in this module (it is the entry point tasks_start shares with the flow-eval path) — see the tasks module doc for the split rationale. HTTP surface for the Task/Run persistence axis (issue #13 ID-hierarchy reconciliation: Blueprint → Task → Run → Step → Attempt).

  • GET /v1/tasks — list every persisted TaskRecord, newest first.
  • GET /v1/tasks/:id — a TaskRecord plus every RunRecord kicked from it.
  • POST /v1/tasks/:id/runs — re-kick an existing Task: mints a fresh RunId, re-resolves the stored blueprint_ref (refreshing Blueprint.default_init_ctx exactly like original launch time — issue #19 ST4), 3-layer-merges it with TaskRecord.input_ctx and an optional RunKickRequest body’s init_ctx_override (see [merge_init_ctx_3layer]), dispatches through TaskApplication::handle_with_run, and returns the new {task_id, run_id} pair. A body-less request (or one that omits both fields) preserves the pre-#19 rekick behavior byte-for-byte.
  • GET /v1/runs/:id — a single RunRecord (step_entries trace included).
  • GET /v1/runs/:id/bindings — requested/effective binding explain from the immutable launch snapshot (never from the current Blueprint).
  • POST /v1/runs/:id/resume — resume an Interrupted Run under the SAME run_id (replay cursor + stored launch-input snapshot).
  • POST /v1/runs/:id/rerun-from — GH #71 Layer A. Rerun a terminal Run (Done / Failed / Interrupted) from a caller-specified step under the SAME run_id; physically truncates the replay log at the cut point so re-dispatch does not collide with the pre-rerun rows. See [run_rerun_from] for the full contract + Known Limitations.

POST /v1/tasks itself (the flow-eval entry point, tasks_start / run_flow_form) stays in crate::lib — it is the pre-existing Operator-inject-aware dispatch path this module’s handlers re-kick through, not a new one. This module owns the read/list/re-kick surface plus the [finalize_run] persistence helper both paths share.

Authorization follows the same convention as the existing POST /v1/tasks entry: no Authorization header is required (the route is open), and the only Operator-session correlation available is the request-body-level operator_sid (see crate::TaskLaunchRequest doc) — this module invents no new auth mechanism.

Structs§

RunBindingDifference
Mechanical requested/effective comparison for one immutable binding.
RunBindingExplainEntry
Explain view for one agent, derived exclusively from the persisted Run snapshot rather than from the current Blueprint registry.
RunBindingsExplainResponse
Response body for GET /v1/runs/:id/bindings.
RunKickRequest
Request body for POST /v1/tasks/:id/runs (issue #19 ST4) — every field is optional, and the body itself is optional (see task_rekick’s Option<Json<Self>> parameter); a caller that sends no body, or {}, or omits a field gets exactly today’s rekick behavior for that layer.
RunKickResponse
Response body for POST /v1/tasks/:id/runs.
RunRerunFromRequest
Request body for POST /v1/runs/:id/rerun-from (GH #71 Layer A).
RunRerunFromResponse
Response body for POST /v1/runs/:id/rerun-from (GH #71 Layer A).
RunResumeResponse
Response body for POST /v1/runs/:id/resume.
RunStepsResponse
Response body for GET /v1/runs/:id/steps.
RunTraceQuery
Query params for GET /v1/runs/:id/trace — see mlua_swarm::store::trace::TraceQuery for semantics (latest wins over after; kind entries are comma-separated prefix matches).
RunTraceResponse
Response body for GET /v1/runs/:id/trace.
RunsListQuery
Query params for GET /v1/runs (the Run collection read).
RunsListResponse
Response body for GET /v1/runs.
TaskDetailResponse
Response body for GET /v1/tasks/:id.
TasksListQuery
Query params for GET /v1/tasks.

Enums§

RunBindingStatus
Whether a Run-scoped binding has only a declaration or also carries a provider attestation accepted by Core.

Functions§

run_bindings_explain
GET /v1/runs/:id/bindings. Explains the exact immutable agent bindings used by this Run. The handler never reads or resolves the current Blueprint; old Runs without a binding snapshot return 422 instead of guessed state.
run_cancel
POST /v1/runs/:id/cancel — record a cancel request on the Run’s trace stream (core.cancel_requested) and mark the Run’s status to Cancelled for still-in-flight rows. Idempotent: repeat calls re-append the trace event but keep the status setter idempotent on the store side. In-flight abort itself remains a v3 carry — the current effect is observational + status marker, matching the swarm_cancel MCP tool’s local semantics but reflected onto the server-side RunTraceStore so GET /v1/runs/:id/trace reflects it too.
run_delete
DELETE /v1/runs/:id — retention prune: deletes the Run row and its trace stream together (404 when the Run row is absent; the trace stream is pruned best-effort either way). Replay rows are untouched — ReplayStore has its own truncation semantics owned by the rerun-from path.
run_get
GET /v1/runs/:id. Returns a single RunRecord (its step_entries trace included).
run_rerun_from
POST /v1/runs/:id/rerun-from — GH #71 Layer A. Re-executes a specific step (and every downstream step) of a terminal Run under the SAME run_id. Mirrors run_resume, with two deltas: it accepts any terminal status (Done / Failed / Interrupted) rather than only Interrupted, and it physically truncates the replay log at the cut point (via crate::AppState::replay_store’s delete_from) so that re-dispatch’s append does not collide with the pre-rerun row and so list_by_run reflects the rerun’s real history rather than the pre-rerun ghost.
run_resume
POST /v1/runs/:id/resume. Resumes an Interrupted Run under the SAME run_id (no new RunId is minted): the stored launch-input snapshot (RunRecord.input_json) is rebuilt into a TaskApplicationInput, a ReplayCursor is built from the Run’s logged step snapshots (ReplayStore::list_by_run), and the flow is re-dispatched with both wired into a fresh RunContext. On dispatch the engine’s replay path returns each already-completed step’s stored value verbatim (cursor hit, no Adapter spawn) and dispatches only the steps that never finished — reconstructing the same final Ctx a restart-free run would have reached.
run_steps
GET /v1/runs/:id/steps — the Run’s terminal per-step stats (StepEntry list) as a standalone sub-resource. Same data GET /v1/runs/:id embeds; split out so stats consumers don’t drag the full RunRecord (launch snapshot etc.) per poll.
run_trace
GET /v1/runs/:id/trace?after=&limit=&latest=&kind=&step=&attempt= — the Run’s TraceEvent stream (the RunTrace rail). Note the trace rail is deliberately uncoupled from RunStore (a trace can outlive or precede its Run row), so an unknown Run id returns an empty list, not 404.
runs_list
GET /v1/runs?task_id=&status=&limit=&offset= — filtered Run collection, newest-first. The collection read that was missing from the Run CRUD surface (only GET /v1/runs/:id existed before the per-step run stats work).
task_get
GET /v1/tasks/:id. Returns the TaskRecord plus every RunRecord kicked from it (RunStore::list_by_task, oldest kick first).
task_rekick
POST /v1/tasks/:id/runs. Re-kicks an existing Task: reads its stored blueprint_ref, re-resolves it through [TaskApplication::resolve] (issue #19 ST4 — refreshes Blueprint.default_init_ctx exactly like original launch time, rather than replaying a launch-time-only snapshot), 3-layer-merges {bp default, TaskRecord.input_ctx, an optional per-Run override} via merge_init_ctx_3layer, resolves the Task-level canonical fields (RunKickRequest.task_input_override, falling back to TaskRecord.task_input_spec), mints a fresh RunId, dispatches through TaskApplication::handle_with_run (Operator-default unless the caller pins a live session via RunKickRequest.operator_sid — the rekick parity for POST /v1/tasks’ own operator_sid; the stored Task carries no persisted Operator preference of its own) plus a freshly-built RunContext (issue #13 run_id propagation, so this kick’s steps get their own step_entries trace), and persists the outcome via [finalize_run].
tasks_list
GET /v1/tasks?limit=N. Lists every persisted TaskRecord, newest first.