Skip to main content

task_rekick

Function task_rekick 

Source
pub async fn task_rekick(
    __arg0: State<AppState>,
    __arg1: Path<String>,
    body: Option<Json<RunKickRequest>>,
) -> Result<(StatusCode, Json<RunKickResponse>), ApiError>
Expand description

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].

The body is optional (Option<Json<RunKickRequest>>) — no body, or a body with both fields absent, preserves the pre-#19 rekick behavior byte-for-byte (must_not_simplify #3).

Issue #35 ST3 ports the GH #33 sync-hang guards from run_flow_form to this handler, both checked before any Task/Run store write: Guard 1 (503) fails fast when the resolved Blueprint declares the operator_delegate spawner-hint layer and no operator is attached; Guard 2 (504) wraps the dispatch await in RunKickRequest.timeout_secs (falling back to the server-wide sync_timeout_secs), marking the Run/Task Failed rather than leaving them Running forever on expiry.