diff --git a/frontend/lib/services/chat_service.dart b/frontend/lib/services/chat_service.dart index 98f9972d..a24aec4f 100644 --- a/frontend/lib/services/chat_service.dart +++ b/frontend/lib/services/chat_service.dart @@ -1,6 +1,8 @@ import 'dart:io'; +import 'dart:typed_data'; import 'package:auto_gpt_flutter_client/models/step_request_body.dart'; import 'package:auto_gpt_flutter_client/utils/rest_api_utility.dart'; +import 'dart:html' as html; /// Service class for performing chat-related operations. class ChatService { @@ -63,8 +65,26 @@ class ChatService { /// /// [taskId] is the ID of the task. /// [artifactId] is the ID of the artifact. - Future> downloadArtifact( - String taskId, String artifactId) async { - return Future.value({'status': 'Not implemented yet'}); + Future downloadArtifact(String taskId, String artifactId) async { + try { + final Uint8List bytes = + await api.getBinary('agent/tasks/$taskId/artifacts/$artifactId'); + + // Create a blob from the Uint8List + final blob = html.Blob([bytes]); + + // Generate a URL from the Blob + final url = html.Url.createObjectUrlFromBlob(blob); + + // Create an anchor HTML element + final anchor = html.AnchorElement(href: url) + ..setAttribute("download", "artifact_$artifactId") + ..click(); + + // Cleanup: Revoke the object URL + html.Url.revokeObjectUrl(url); + } catch (e) { + throw Exception('An error occurred while downloading the artifact: $e'); + } } } diff --git a/frontend/lib/utils/rest_api_utility.dart b/frontend/lib/utils/rest_api_utility.dart index dde50e17..6884f806 100644 --- a/frontend/lib/utils/rest_api_utility.dart +++ b/frontend/lib/utils/rest_api_utility.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:typed_data'; import 'package:http/http.dart' as http; class RestApiUtility { @@ -32,4 +33,19 @@ class RestApiUtility { throw Exception('Failed to post data'); } } + + Future getBinary(String endpoint) async { + final response = await http.get( + Uri.parse('$_baseUrl/$endpoint'), + headers: {"Content-Type": "application/octet-stream"}, + ); + + if (response.statusCode == 200) { + return response.bodyBytes; + } else if (response.statusCode == 404) { + throw Exception('Resource not found'); + } else { + throw Exception('Failed to load binary data'); + } + } } diff --git a/frontend/pubspec.lock b/frontend/pubspec.lock index 85634a73..7d76dc80 100644 --- a/frontend/pubspec.lock +++ b/frontend/pubspec.lock @@ -41,6 +41,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.2" + csslib: + dependency: transitive + description: + name: csslib + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + url: "https://pub.dev" + source: hosted + version: "1.0.0" cupertino_icons: dependency: "direct main" description: @@ -112,6 +120,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.0" + html: + dependency: "direct main" + description: + name: html + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + url: "https://pub.dev" + source: hosted + version: "0.15.4" http: dependency: "direct main" description: diff --git a/frontend/pubspec.yaml b/frontend/pubspec.yaml index f546fb0c..ec9a08c0 100644 --- a/frontend/pubspec.yaml +++ b/frontend/pubspec.yaml @@ -39,6 +39,7 @@ dependencies: provider: ^6.0.5 http: ^1.1.0 shared_preferences: ^2.2.1 + dart:html: any dev_dependencies: flutter_test: