Add Host Agent local console task cancellation (task-cancellation 7.1-7.3)
- New internal API route POST /internal/v1/hosts/{host_id}/tasks/{task_id}/cancel,
authenticated via the host's own bearer credential (authorize_host) with an
ownership check, since host tokens carry no scopes and cannot reach the
public SDK's tasks:submit-scoped cancel endpoint.
- HostAgentClient.cancel_task() calls the new internal route directly.
- create_console_app() gains a cancel_task callable with automatic default
wiring from host_client, so production app.py needs no changes.
- Local console: POST /tasks/{task_id}/cancel route resolves the local
execution id to its Cloud source_task_id before cancelling, and the task
detail page/template show a Cancel button plus notice/error banners.
- Tests across all three layers: internal API route, Jinja2 template
rendering, and FastAPI console route behavior.
This commit is contained in:
@@ -14,6 +14,7 @@ from cloud.internal_api.models import (
|
||||
DeviceSnapshotModel,
|
||||
HeartbeatResponse,
|
||||
HostEnrollmentResponse,
|
||||
HostTaskCancellationResponse,
|
||||
HostTaskSubmissionResponse,
|
||||
LeaseRenewalResponse,
|
||||
TaskProgressModel,
|
||||
@@ -219,6 +220,17 @@ class HostAgentClient:
|
||||
"control plane returned malformed success payload"
|
||||
) from exc
|
||||
|
||||
async def cancel_task(self, task_id: str) -> HostTaskCancellationResponse:
|
||||
response = await self._client.request(
|
||||
"POST",
|
||||
f"/internal/v1/hosts/{self.config.host_id}/tasks/{task_id}/cancel",
|
||||
json={"host_id": self.config.host_id},
|
||||
headers={"Authorization": f"Bearer {self.config.token}"},
|
||||
)
|
||||
if not response.is_success:
|
||||
_raise_api_error(response)
|
||||
return HostTaskCancellationResponse.model_validate(response.json())
|
||||
|
||||
async def claim(self) -> AssignmentModel | None:
|
||||
response = await self._request(
|
||||
"POST",
|
||||
|
||||
Reference in New Issue
Block a user