feat: checkpoint device agent runtime milestones
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Register a device
|
||||
The system SHALL expose `POST /console/devices` accepting `driver_type`, `connection_info`, and an optional `name`, persist the configuration, and register the device with the running `DeviceManager`. Unsupported `driver_type` values SHALL be rejected.
|
||||
|
||||
#### Scenario: Register a supported device
|
||||
- **WHEN** an operator posts `{"driver_type": "wda", "connection_info": {"server_url": "http://127.0.0.1:4723", "udid": "abc123"}}` to `POST /console/devices`
|
||||
- **THEN** the response is a `201` with the new device's id and status `idle`, the device appears in `GET /console/devices`, and its configuration is persisted
|
||||
|
||||
#### Scenario: Reject unsupported driver type
|
||||
- **WHEN** an operator posts a device with `driver_type` not in the supported set (currently `wda`)
|
||||
- **THEN** the response is a `400` and no device is registered or persisted
|
||||
|
||||
### Requirement: Unregister a device
|
||||
The system SHALL expose `DELETE /console/devices/{device_id}` that disconnects and removes the device from `DeviceManager` and deletes its persisted configuration, or returns a `404` if the device is unknown.
|
||||
|
||||
#### Scenario: Unregister a known device
|
||||
- **WHEN** an operator calls `DELETE /console/devices/{device_id}` for a registered device
|
||||
- **THEN** the response is a `204`, the device no longer appears in `GET /console/devices`, and its persisted configuration is removed
|
||||
|
||||
#### Scenario: Unregister an unknown device
|
||||
- **WHEN** an operator calls `DELETE /console/devices/{device_id}` for a device id that is not registered
|
||||
- **THEN** the response is a `404`
|
||||
|
||||
### Requirement: Persisted devices reload on startup
|
||||
The system SHALL re-register every persisted device configuration with `DeviceManager` automatically when the application starts, without requiring manual re-registration.
|
||||
|
||||
#### Scenario: Restart with previously registered devices
|
||||
- **WHEN** the application starts and one or more device configurations exist in the persisted device config store
|
||||
- **THEN** each persisted device appears in `GET /console/devices` immediately after startup, without any additional operator action
|
||||
|
||||
### Requirement: View and update runtime parameters
|
||||
The system SHALL expose `GET /console/config` returning current adjustable runtime parameters (currently the task runner's `max_steps`) and `PUT /console/config` to update them, applying the change to the running task runner immediately and persisting it across restarts.
|
||||
|
||||
#### Scenario: View current runtime parameters
|
||||
- **WHEN** an operator calls `GET /console/config`
|
||||
- **THEN** the response is a `200` including the current `max_steps` value
|
||||
|
||||
#### Scenario: Update max_steps
|
||||
- **WHEN** an operator calls `PUT /console/config` with `{"max_steps": 30}`
|
||||
- **THEN** the response is a `200` with the updated value, subsequently started tasks (and the next iteration of any in-flight task) use the new `max_steps`, and the value is persisted so it survives a restart
|
||||
|
||||
#### Scenario: Reject invalid runtime parameter value
|
||||
- **WHEN** an operator calls `PUT /console/config` with a non-positive `max_steps` (e.g. `0` or `-1`)
|
||||
- **THEN** the response is a `400` and the previous value remains in effect
|
||||
@@ -0,0 +1,49 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: List device status
|
||||
The system SHALL expose `GET /console/devices` returning every registered device's id, name, status (`idle`/`busy`/`offline`/`error`), and driver type, reusing `DeviceManager.list_devices()`.
|
||||
|
||||
#### Scenario: Devices are registered
|
||||
- **WHEN** an operator calls `GET /console/devices` while one or more devices are registered
|
||||
- **THEN** the response is a `200` with a JSON array containing one entry per device with its current `status`
|
||||
|
||||
#### Scenario: No devices registered
|
||||
- **WHEN** an operator calls `GET /console/devices` while no devices are registered
|
||||
- **THEN** the response is a `200` with an empty JSON array
|
||||
|
||||
### Requirement: List tasks
|
||||
The system SHALL expose `GET /console/tasks` returning all tasks known to `TaskMetadataStore`, most recently created first, with optional `device_id` and `status` query filters.
|
||||
|
||||
#### Scenario: List all tasks
|
||||
- **WHEN** an operator calls `GET /console/tasks` with no query parameters
|
||||
- **THEN** the response is a `200` with a JSON array of tasks ordered by `created_at` descending
|
||||
|
||||
#### Scenario: Filter by device
|
||||
- **WHEN** an operator calls `GET /console/tasks?device_id=<id>`
|
||||
- **THEN** the response contains only tasks whose `device_id` matches `<id>`
|
||||
|
||||
#### Scenario: Filter by status
|
||||
- **WHEN** an operator calls `GET /console/tasks?status=running`
|
||||
- **THEN** the response contains only tasks whose `status` equals `running`
|
||||
|
||||
### Requirement: Task detail
|
||||
The system SHALL expose `GET /console/tasks/{task_id}` returning the full task record, or a `404` if the task does not exist.
|
||||
|
||||
#### Scenario: Task exists
|
||||
- **WHEN** an operator calls `GET /console/tasks/{task_id}` for a known task id
|
||||
- **THEN** the response is a `200` with the task's goal, device_id, status, timestamps, and failure_reason (if any)
|
||||
|
||||
#### Scenario: Task does not exist
|
||||
- **WHEN** an operator calls `GET /console/tasks/{task_id}` for an unknown task id
|
||||
- **THEN** the response is a `404`
|
||||
|
||||
### Requirement: Task timeline replay
|
||||
The system SHALL expose `GET /console/tasks/{task_id}/timeline` returning the ordered list of execution steps recorded for the task, each including its scene, prompt, tool call, result, timestamp, and a base64-encoded screenshot when one was captured for that step.
|
||||
|
||||
#### Scenario: Task has recorded steps
|
||||
- **WHEN** an operator calls `GET /console/tasks/{task_id}/timeline` for a task that executed at least one step
|
||||
- **THEN** the response is a `200` with a JSON array ordered by step `index` ascending, each entry including `image_base64` when a screenshot was captured for that step
|
||||
|
||||
#### Scenario: Task has no recorded steps
|
||||
- **WHEN** an operator calls `GET /console/tasks/{task_id}/timeline` for a task with no timeline history (e.g. it failed before its first step)
|
||||
- **THEN** the response is a `200` with an empty JSON array
|
||||
@@ -0,0 +1,45 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Device status dashboard
|
||||
The web console SHALL display a list of registered devices with their current status, fetched from `console-status-api`, and SHALL show an explicit empty state when no devices are registered.
|
||||
|
||||
#### Scenario: Devices registered
|
||||
- **WHEN** an operator opens the dashboard while devices are registered
|
||||
- **THEN** each device is shown with its name/id and current status, refreshed without a full page reload
|
||||
|
||||
#### Scenario: No devices registered
|
||||
- **WHEN** an operator opens the dashboard while no devices are registered
|
||||
- **THEN** an empty-state message is shown inviting the operator to add a device
|
||||
|
||||
### Requirement: Task list and timeline replay
|
||||
The web console SHALL let an operator browse the task list, open a task's detail view, and step through its recorded timeline including screenshots.
|
||||
|
||||
#### Scenario: Browse tasks
|
||||
- **WHEN** an operator opens the task list view
|
||||
- **THEN** tasks are shown most-recent-first with their goal, device, and status, and can be filtered by device or status
|
||||
|
||||
#### Scenario: Replay a task's timeline
|
||||
- **WHEN** an operator opens a completed or failed task's detail view
|
||||
- **THEN** the console renders each recorded step in order, showing its tool call, result, and screenshot (when available)
|
||||
|
||||
### Requirement: Device configuration
|
||||
The web console SHALL let an operator register a new device (choosing a supported driver type and entering its connection info) and remove an existing device, surfacing any validation error returned by `console-config-api`.
|
||||
|
||||
#### Scenario: Add a device successfully
|
||||
- **WHEN** an operator submits the add-device form with valid driver type and connection info
|
||||
- **THEN** the new device appears in the dashboard without a page reload
|
||||
|
||||
#### Scenario: Add a device with invalid input
|
||||
- **WHEN** an operator submits the add-device form with an unsupported driver type
|
||||
- **THEN** the console displays the error returned by the API and does not add the device to the list
|
||||
|
||||
#### Scenario: Remove a device
|
||||
- **WHEN** an operator confirms removal of a registered device
|
||||
- **THEN** the device disappears from the dashboard without a page reload
|
||||
|
||||
### Requirement: Runtime parameter configuration
|
||||
The web console SHALL let an operator view and edit adjustable runtime parameters (currently `max_steps`) through a settings form.
|
||||
|
||||
#### Scenario: Update a runtime parameter
|
||||
- **WHEN** an operator changes `max_steps` in the settings form and saves
|
||||
- **THEN** the console shows the updated value on success, or the validation error if the API rejects it
|
||||
Reference in New Issue
Block a user