Added Agent Details including Task Details

This commit is contained in:
2026-09-01 13:57:08 +02:00
parent 7a9ce396f4
commit 525aaa6555
7 changed files with 469 additions and 39 deletions
+25 -34
View File
@@ -2,57 +2,48 @@ import 'package:ac_web/Api/JsonReader.dart';
/// Dart counterpart of the backend `AgentTaskDto`.
///
/// The exact shape of the backend dto is not final yet, therefore everything
/// except the name is treated as optional. Unknown properties are simply
/// ignored, so this dto keeps working while the api grows.
/// A task is one piece of work an agent is currently busy with. While it runs
/// the agent appends short lines to [statusUpdates], so the list doubles as
/// the history of the task.
class AgentTaskDto {
const AgentTaskDto({
required this.name,
this.id,
this.description,
this.status,
this.progress,
this.createdAt,
this.finishedAt,
required this.title,
this.startTime,
this.statusUpdates = const <String>[],
});
final String name;
final String? id;
final String? description;
final String? status;
final String title;
/// Completion between 0 and 100 if the api reports it.
final int? progress;
/// Moment the agent picked the task up, if the api reports it.
final DateTime? startTime;
final DateTime? createdAt;
final DateTime? finishedAt;
/// Every status line the agent reported so far, oldest first.
final List<String> statusUpdates;
bool get isFinished => finishedAt != null;
bool get hasStatusUpdates => statusUpdates.isNotEmpty;
/// The most recent status line, or null while the agent did not report one.
String? get latestStatus => statusUpdates.isEmpty ? null : statusUpdates.last;
factory AgentTaskDto.fromJson(Map<String, dynamic> json) {
return AgentTaskDto(
name: JsonReader.optionalString(json, 'Name') ?? '',
id: JsonReader.optionalString(json, 'Id'),
description: JsonReader.optionalString(json, 'Description'),
status: JsonReader.optionalString(json, 'Status'),
progress: JsonReader.optionalInt(json, 'Progress'),
createdAt: JsonReader.optionalDateTime(json, 'CreatedAt'),
finishedAt: JsonReader.optionalDateTime(json, 'FinishedAt'),
// Older builds of the api called the property "Name".
title: JsonReader.optionalString(json, 'Title') ??
JsonReader.optionalString(json, 'Name') ??
'',
startTime: JsonReader.optionalDateTime(json, 'StartTime'),
statusUpdates: JsonReader.stringList(json, 'StatusUpdates'),
);
}
Map<String, dynamic> toJson() {
return <String, dynamic>{
'Name': name,
if (id != null) 'Id': id,
if (description != null) 'Description': description,
if (status != null) 'Status': status,
if (progress != null) 'Progress': progress,
if (createdAt != null) 'CreatedAt': createdAt!.toIso8601String(),
if (finishedAt != null) 'FinishedAt': finishedAt!.toIso8601String(),
'Title': title,
if (startTime != null) 'StartTime': startTime!.toIso8601String(),
'StatusUpdates': statusUpdates,
};
}
@override
String toString() => 'AgentTaskDto(name: $name, status: $status)';
String toString() => 'AgentTaskDto(title: $title, updates: ${statusUpdates.length})';
}
+12
View File
@@ -85,6 +85,18 @@ class JsonReader {
return int.tryParse(raw.toString());
}
/// Maps a json array of plain values onto a list of strings.
static List<String> stringList(Map<String, dynamic> json, String key) {
final raw = value(json, key);
if (raw is! List) {
return const <String>[];
}
return raw
.where((entry) => entry != null)
.map((entry) => entry.toString())
.toList(growable: false);
}
/// Maps a json array onto a list of models, tolerating a missing property.
static List<T> list<T>(
Map<String, dynamic> json,