feat: add download doc button

This commit is contained in:
Udhay-Adithya
2025-09-24 21:01:24 +05:30
parent 92ea46c519
commit 75c0ab2b70
4 changed files with 51 additions and 2 deletions

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../features/chat/models/chat_models.dart';
import '../../../features/chat/viewmodel/chat_viewmodel.dart';
@@ -8,6 +9,8 @@ import '../../services/openapi_import_service.dart';
import '../../../features/chat/view/widgets/openapi_operation_picker_dialog.dart';
import 'package:openapi_spec/openapi_spec.dart';
import '../../providers/dashbot_window_notifier.dart';
import '../../../../utils/save_utils.dart';
import '../../../../utils/utils.dart';
/// Base mixin for action widgets.
mixin DashbotActionMixin {
@@ -308,6 +311,37 @@ class DashbotGeneratedCodeBlock extends StatelessWidget
}
}
class DashbotDownloadDocButton extends ConsumerWidget with DashbotActionMixin {
@override
final ChatAction action;
const DashbotDownloadDocButton({super.key, required this.action});
@override
Widget build(BuildContext context, WidgetRef ref) {
final docContent = (action.value is String) ? action.value as String : '';
final filename = action.path ?? 'api-documentation';
return ElevatedButton.icon(
icon: const Icon(Icons.download, size: 16),
label: const Text('Download Documentation'),
onPressed: docContent.isEmpty
? null
: () async {
final scaffoldMessenger = ScaffoldMessenger.of(context);
final contentBytes = Uint8List.fromList(docContent.codeUnits);
await saveToDownloads(
scaffoldMessenger,
content: contentBytes,
mimeType: 'text/markdown',
ext: 'md',
name: filename,
);
},
);
}
}
/// Factory to map an action to a widget.
class DashbotActionWidgetFactory {
static Widget? build(ChatAction action) {
@@ -335,6 +369,8 @@ class DashbotActionWidgetFactory {
return DashbotApplyCurlButton(action: action);
case ChatActionType.applyOpenApi:
return DashbotApplyOpenApiButton(action: action);
case ChatActionType.downloadDoc:
return DashbotDownloadDocButton(action: action);
case ChatActionType.noAction:
// If downstream requests, render an Import Now for OpenAPI contexts
if (action.action == 'import_now_openapi') {

View File

@@ -332,7 +332,9 @@ TASK
OUTPUT FORMAT (STRICT)
- Return ONLY a single JSON object. No markdown wrapper outside JSON.
- SCHEMA: {"explnation": "<complete markdown>", "actions": []}
- SCHEMA: {"explnation": "<complete markdown>", "actions": [{"action": "download_doc", "target": "documentation", "field": "markdown", "path": "api-documentation", "value": "<complete markdown>"}]}
- The "explnation" field should contain the complete markdown documentation
- The "actions" array should contain a single download action with the same markdown content in the "value" field
MARKDOWN FORMATTING REQUIREMENTS
- Use proper headers (# ## ###)
@@ -343,7 +345,7 @@ MARKDOWN FORMATTING REQUIREMENTS
- Include relevant badges or status indicators
REFUSAL TEMPLATE (when off-topic), JSON only:
{"explnation":"I am Dashbot, an AI assistant focused specifically on API development tasks within API Dash. My capabilities are limited to explaining API responses, debugging requests, generating documentation, creating tests, visualizing API data, and generating integration code. Therefore, I cannot answer questions outside of this scope. How can I assist you with an API-related task?","action":null}
{"explnation":"I am Dashbot, an AI assistant focused specifically on API development tasks within API Dash. My capabilities are limited to explaining API responses, debugging requests, generating documentation, creating tests, visualizing API data, and generating integration code. Therefore, I cannot answer questions outside of this scope. How can I assist you with an API-related task?","actions":[]}
RETURN THE JSON ONLY.
</system_prompt>

View File

@@ -82,6 +82,7 @@ class AutoFixService {
case ChatActionType.showLanguages:
case ChatActionType.noAction:
case ChatActionType.uploadAsset:
case ChatActionType.downloadDoc:
return null;
}
}

View File

@@ -108,6 +108,7 @@ enum ChatActionType {
showLanguages,
applyCurl,
applyOpenApi,
downloadDoc,
other,
noAction,
uploadAsset,
@@ -119,6 +120,7 @@ enum ChatActionTarget {
test,
code,
attachment,
documentation,
}
ChatActionType _chatActionTypeFromString(String s) {
@@ -143,6 +145,8 @@ ChatActionType _chatActionTypeFromString(String s) {
return ChatActionType.applyCurl;
case 'apply_openapi':
return ChatActionType.applyOpenApi;
case 'download_doc':
return ChatActionType.downloadDoc;
case 'upload_asset':
return ChatActionType.uploadAsset;
case 'no_action':
@@ -176,6 +180,8 @@ String chatActionTypeToString(ChatActionType t) {
return 'apply_curl';
case ChatActionType.applyOpenApi:
return 'apply_openapi';
case ChatActionType.downloadDoc:
return 'download_doc';
case ChatActionType.other:
return 'other';
case ChatActionType.noAction:
@@ -197,6 +203,8 @@ ChatActionTarget _chatActionTargetFromString(String s) {
return ChatActionTarget.code;
case 'attachment':
return ChatActionTarget.attachment;
case 'documentation':
return ChatActionTarget.documentation;
default:
return ChatActionTarget.httpRequestModel;
}
@@ -214,6 +222,8 @@ String chatActionTargetToString(ChatActionTarget t) {
return 'code';
case ChatActionTarget.attachment:
return 'attachment';
case ChatActionTarget.documentation:
return 'documentation';
}
}