feat: surface task execution progress across Host Agent and Cloud

Host Agent now persists step-level execution detail locally (via a real
TaskMetadataStore/Timeline wired into TaskRunner) and reports a bounded
in-progress snapshot piggybacked on lease renewal. Cloud persists that
snapshot per active assignment and exposes it through the existing task
list/detail query path; Cloud Console renders it as a live badge. Host
Agent's local console gains authenticated, read-only task list and
detail/timeline pages (same-origin, server-rendered) with inlined
screenshots.

Also fixes a pre-existing gap in the shared Timeline: the actual
per-step LLM prompt is now recorded instead of the task goal, benefiting
both Runtime and Host Agent consoles. When a host uses the cloud planner
transport, each decide call's prompt and resulting tool decision are
durably logged in a new planner_decision_log table (with bounded
retention) and browsable from Cloud Console; direct-transport hosts
explicitly surface a "not reported" state.

Includes Alembic migrations 0008 (progress columns on scheduled_tasks)
and 0009 (planner_decision_log), bounded Host-Agent-local retention,
dual-backend repository parity, and Vitest + pytest coverage. Task 6.5
(manual end-to-end device verification) remains.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 12:47:49 +08:00
co-authored by Claude Opus 4.6
parent c049c3c1b1
commit ec261d57c2
59 changed files with 3801 additions and 122 deletions
@@ -0,0 +1,34 @@
## ADDED Requirements
### Requirement: Cloud Control Plane persists each resolved planner decision for later retrieval
The Cloud Control Plane's planner-decision endpoint SHALL, for each request it successfully resolves to a tool-call decision, persist the request's system prompt, user prompt, the resolved tool name and arguments, and an assigned step index (scoped to the request's `task_id`/`attempt`) to a durable, bounded-retention store, in addition to returning the decision to the requesting Host Agent. The Cloud Control Plane SHALL NOT persist screenshot bytes from these requests.
#### Scenario: A planner-decision request resolves successfully
- **WHEN** the Cloud Control Plane resolves a planner-decision request to a tool-call decision
- **THEN** it persists the request's system prompt, user prompt, the resolved tool name and arguments, and a step index for that `task_id`/`attempt`, before returning the decision to the Host Agent
#### Scenario: A planner-decision request fails
- **WHEN** the configured provider call fails and the endpoint returns a structured failure response
- **THEN** no row is persisted for that request
#### Scenario: A screenshot was included in the request
- **WHEN** a planner-decision request includes a screenshot
- **THEN** the screenshot bytes are used only to call the LLM provider and are not written to the persisted decision log
### Requirement: Persisted planner decisions are retained within a bounded window
The Cloud Control Plane SHALL prune persisted planner decisions once their owning task has been in a terminal state for longer than a configurable retention window, so that indefinite operation does not cause unbounded growth of the decision log.
#### Scenario: A task's retention window has elapsed since reaching a terminal state
- **WHEN** a task reached a terminal state more than the configured retention window ago
- **THEN** the Cloud Control Plane removes that task's persisted planner decisions
#### Scenario: A task is still active or within its retention window
- **WHEN** a task is still active, or reached a terminal state less than the configured retention window ago
- **THEN** its persisted planner decisions remain available for query
### Requirement: Cloud-side planner decision history is scoped to hosts using the cloud-proxy transport
The Cloud Control Plane's persisted planner decision log SHALL only ever contain entries for hosts whose planner calls were routed through the cloud-proxy transport; it SHALL NOT contain entries, synthesized or otherwise, for hosts using the direct-to-provider transport.
#### Scenario: A host uses the direct-to-provider transport
- **WHEN** a Host Agent configured for the direct-to-provider transport executes an assignment
- **THEN** no planner decision entries for that assignment appear in the Cloud Control Plane's persisted decision log
@@ -0,0 +1,38 @@
## ADDED Requirements
### Requirement: Cloud Control Plane exposes the latest in-progress step status for an active assignment
The Cloud Control Plane's existing task query surface SHALL include the latest reported step index, step status, and summary for any assignment that has an in-progress Host Agent execution, alongside the task's existing status fields.
#### Scenario: An assignment has reported progress
- **WHEN** an operator queries a task that has an active, in-progress assignment with previously reported step progress
- **THEN** the response includes that step's index, status, and summary alongside the task's existing fields
#### Scenario: An assignment has no reported progress yet
- **WHEN** an operator queries a task whose active assignment has not yet reported any progress
- **THEN** the response omits progress fields rather than showing stale or default values
#### Scenario: An assignment has reached a terminal state
- **WHEN** an operator queries a task whose assignment has already completed (succeeded or failed)
- **THEN** the response does not present the last in-progress step as current status; the task's terminal status and result take precedence
### Requirement: Cloud Console renders live step progress for in-progress tasks
Cloud Console SHALL display the current step index, status, and summary for a task with an active, in-progress Host Agent execution, refreshed on its existing polling interval, without requiring a new push channel.
#### Scenario: Operator views an in-progress task
- **WHEN** an operator opens a task detail view for a task with an active in-progress assignment
- **THEN** Cloud Console shows the latest known step index, status, and summary, updating on subsequent polls as new progress is reported
#### Scenario: Operator views a task with no in-progress execution
- **WHEN** an operator opens a task detail view for a queued, terminal, or otherwise not-currently-executing task
- **THEN** Cloud Console does not display stale in-progress step information
### Requirement: Cloud Console displays a task's full LLM interaction history
Cloud Console SHALL provide a view, for a given task, listing each persisted planner decision in step order, including its full prompt and resulting decision, sourced from the Cloud Control Plane's persisted planner decision log.
#### Scenario: Task has persisted planner decisions
- **WHEN** an operator opens the LLM interaction history view for a task that has one or more persisted planner decisions
- **THEN** Cloud Console shows each decision in step order with its prompt and resulting tool call
#### Scenario: Task's host used the direct-to-provider transport
- **WHEN** an operator opens the LLM interaction history view for a task whose host used the direct-to-provider transport
- **THEN** Cloud Console indicates that no LLM interaction history is available because the host does not report it, rather than showing an empty history with no explanation
@@ -0,0 +1,34 @@
## ADDED Requirements
### Requirement: Host Agent local console exposes step-level status for the current assignment
The Host Agent's local console SHALL display, for its currently executing assignment, the current step index, step status, and a short summary, sourced from the Host Agent's local task metadata store, refreshed on the console's existing polling interval.
#### Scenario: An assignment is currently executing
- **WHEN** an operator views the Host Agent local console dashboard while an assignment is executing
- **THEN** the dashboard shows the current step index, step status, and a short summary for that assignment, updating on subsequent polls
#### Scenario: No assignment is currently executing
- **WHEN** an operator views the dashboard while the Host Agent is idle
- **THEN** the dashboard shows no in-progress step information
### Requirement: Host Agent local console exposes read-only task history with per-step detail and screenshots
The Host Agent's local console SHALL provide authenticated, read-only pages listing recently executed tasks and, for a selected task, its full per-step history including any captured screenshots, sourced from the Host Agent's local task metadata store and timeline.
#### Scenario: Operator lists recent tasks
- **WHEN** an authenticated operator opens the Host Agent local console's task list page
- **THEN** it shows tasks from the local task metadata store, most recent first, including tasks that have already reached a terminal state
#### Scenario: Operator inspects a completed task's step history
- **WHEN** an authenticated operator opens the detail page for a specific completed task
- **THEN** the page shows each recorded step in order, including its tool call, result, and any captured screenshot
#### Scenario: Unauthenticated request
- **WHEN** a request to the task list or task detail pages is made without a valid Host Agent console session
- **THEN** the Host Agent rejects the request the same way it rejects unauthenticated requests to its other console pages
### Requirement: Host Agent local console task pages require no new cross-origin surface
The Host Agent local console's task pages SHALL be served same-origin from the Host Agent's existing web application, without introducing new CORS allowances or a dependency on the separate Runtime `console/` frontend.
#### Scenario: Task pages are requested
- **WHEN** an operator's browser requests the Host Agent local console's task pages
- **THEN** the pages are served by the Host Agent's own application using its existing session/CSRF protections, with no additional cross-origin configuration required
@@ -0,0 +1,23 @@
## ADDED Requirements
### Requirement: Host Agent reports execution progress alongside lease renewal
The Host Agent SHALL optionally include a bounded, screenshot-free progress summary (current step index, step status, and a short plain-text summary) in its periodic lease-renewal request for an active assignment, and the control plane SHALL accept and store only the most recent such summary per active assignment.
#### Scenario: Progress is available at renewal time
- **WHEN** the Host Agent renews the lease for an in-progress assignment and has a current step index, status, and summary available
- **THEN** the renewal request includes that progress summary and the control plane overwrites any previously stored progress for that assignment with it
#### Scenario: Progress is not available at renewal time
- **WHEN** the Host Agent renews a lease without a progress summary available (e.g. before the first step completes)
- **THEN** the renewal request omits the progress field and any previously stored progress for that assignment is left unchanged
#### Scenario: Assignment reaches a terminal state
- **WHEN** an assignment's terminal result is recorded
- **THEN** the control plane's stored progress for that assignment is no longer treated as current and is not exposed as an in-progress status
### Requirement: Progress reports exclude screenshot and scene payloads
The control plane SHALL reject or ignore any progress field on a renewal request that includes screenshot, scene, or other bulk payload data beyond the bounded step index, status, and short text summary.
#### Scenario: Renewal request includes an oversized or non-text summary
- **WHEN** a Host Agent submits a progress summary exceeding the configured length bound
- **THEN** the control plane truncates or rejects the oversized field without failing the underlying lease renewal
@@ -0,0 +1,30 @@
## ADDED Requirements
### Requirement: Host Agent records step-level execution detail for its in-process TaskRunner
The Host Agent SHALL construct its in-process `TaskRunner` with a durable metadata store and timeline so that every step transition (status, index, the actual prompt submitted to the LLM for that step, the model's resulting decision, result, and screenshot when captured) is persisted as it happens, rather than discarded when the assignment completes. The persisted prompt SHALL be the prompt actually sent to the LLM for that specific step, not the task's overall goal.
#### Scenario: A step completes during goal execution
- **WHEN** the Host Agent's `TaskRunner` completes a step while executing an assigned goal
- **THEN** the step's status, index, the actual per-step LLM prompt and response, tool call, result, and any captured screenshot are persisted to the Host Agent's local task metadata store and timeline before the next step begins
#### Scenario: An assignment finishes
- **WHEN** an assignment reaches a terminal state (succeeded or failed)
- **THEN** its full step history remains queryable from the Host Agent's local store after the in-memory `Task` object is discarded
### Requirement: Host-Agent-local task history is retained within a bounded window
The Host Agent SHALL prune persisted task metadata, timeline records, and associated screenshot artifacts once they exceed a configurable retention window or count, so that indefinite process uptime does not cause unbounded local disk growth.
#### Scenario: Retention window is exceeded
- **WHEN** a persisted task's age or position exceeds the configured retention threshold
- **THEN** the Host Agent removes that task's metadata row, timeline records, and screenshot artifacts from local storage
#### Scenario: Retention has not been exceeded
- **WHEN** a persisted task is within the configured retention threshold
- **THEN** its metadata, timeline records, and screenshot artifacts remain available for query
### Requirement: Host Agent local task storage is isolated from an unrelated local Runtime
The Host Agent SHALL use a configurable, Host-Agent-specific database and artifact path for its task metadata store and timeline, distinct from any local Runtime API's own task storage path, so that the two processes cannot silently collide or share state when run on the same machine.
#### Scenario: Host Agent and local Runtime run on the same machine
- **WHEN** both a Host Agent process and a local Runtime API process run on the same machine with their default configurations
- **THEN** each process reads and writes its own task metadata store and timeline without observing or modifying the other's data