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.
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_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.
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 (the unadorned Operator-default path — no per-request Operator override support here, unlike POST /v1/tasks; the stored Task carries no such preferences) 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.