diff --git a/backend/druks/durable/schemas.py b/backend/druks/durable/schemas.py index d74f19ce..401c09ec 100644 --- a/backend/druks/durable/schemas.py +++ b/backend/druks/durable/schemas.py @@ -92,7 +92,7 @@ class RunResponse(Schema): # The durable kind ("software_factory.build"); ``label`` is its display name ("Build"). kind: str label: str - state: Literal["scheduled", "running", "parked", "finished", "failed", "cancelled"] + state: RunState failure: str | None = None gate: str | None = None # The structured ask the parked run declared at ``Gate.wait(input_request=…)`` — @@ -115,7 +115,7 @@ def from_run( id=run.id, kind=run.kind, label=get_display_label(run.kind), - state=run.state, # type: ignore[arg-type] + state=RunState(run.state), failure=run.failure_message(), gate=run.input_gate, input_request=input_request, diff --git a/backend/tests/test_durable_schemas.py b/backend/tests/test_durable_schemas.py index 8ffa7ad5..c942e325 100644 --- a/backend/tests/test_durable_schemas.py +++ b/backend/tests/test_durable_schemas.py @@ -3,6 +3,8 @@ from druks.durable.exceptions import GateTimeout from druks.durable.models import AgentCall, Run from druks.durable.reads import _status +from druks.durable.schemas import RunResponse +from druks.models import Base from druks_field_notes.workflows import Summarize @@ -136,3 +138,10 @@ async def test_status_falls_back_to_the_terminal_call_error_when_failure_is_null ) ] assert (await _status_of(runs)).failure == "crashed in implement" + + +def test_a_run_response_carries_an_orphaned_run(): + # Every state a run derives projects onto a run response, orphaned included. + run = _run("gone", Summarize.kind, RunState.ORPHANED) + run.created_at = run.updated_at = Base.utc_now() + assert RunResponse.from_run(run, input_request=None).state == RunState.ORPHANED