diff --git a/doc/user_guide/dashbot_user_guide.md b/doc/user_guide/dashbot_user_guide.md index 50a679e7..628985ef 100644 --- a/doc/user_guide/dashbot_user_guide.md +++ b/doc/user_guide/dashbot_user_guide.md @@ -4,9 +4,9 @@ Dashbot is your in-app helper for working with APIs inside API Dash. It explains ## Before You Start -- Configure an AI model: Open the AI Request settings and set your preferred provider/model and API key. Dashbot needs this to generate answers. If not configured, you will see a message asking you to set it up. -- Pick or create a request: Dashbot works best when a request is selected, especially for Explain, Debug, Tests, Docs, and Code. -- Network access: Some features pull insights only from your current request and input. No external API calls are made by Dashbot itself (outside your configured AI provider). +- **Configure an AI model** : Open the AI Request settings and set your preferred provider/model and API key. Dashbot needs this to generate answers. If not configured, you will see a message asking you to set it up. +- **Pick or create a request** : Dashbot works best when a request is selected, especially for Explain, Debug, Tests, Docs, and Code. +- **Network access** : Some features pull insights only from your current request and input. No external API calls are made by Dashbot itself (outside your configured AI provider). ## Open Dashbot - Floating window: Click the Dashbot button to open it as a floating panel. diff --git a/lib/dashbot/features/chat/viewmodel/chat_viewmodel.dart b/lib/dashbot/features/chat/viewmodel/chat_viewmodel.dart index db78a47d..0eb21ece 100644 --- a/lib/dashbot/features/chat/viewmodel/chat_viewmodel.dart +++ b/lib/dashbot/features/chat/viewmodel/chat_viewmodel.dart @@ -107,6 +107,8 @@ class ChatViewmodel extends StateNotifier { ); } else if (type == ChatMessageType.importCurl) { final rqId = _currentRequest?.id ?? 'global'; + // Briefly toggle loading to indicate processing of the import flow prompt + state = state.copyWith(isGenerating: true, currentStreamingResponse: ''); _addMessage( rqId, ChatMessage( @@ -118,9 +120,11 @@ class ChatViewmodel extends StateNotifier { messageType: ChatMessageType.importCurl, ), ); + state = state.copyWith(isGenerating: false, currentStreamingResponse: ''); return; } else if (type == ChatMessageType.importOpenApi) { final rqId = _currentRequest?.id ?? 'global'; + state = state.copyWith(isGenerating: true, currentStreamingResponse: ''); final uploadAction = ChatAction.fromJson({ 'action': 'upload_asset', 'target': 'attachment', @@ -152,6 +156,7 @@ class ChatViewmodel extends StateNotifier { if (_looksLikeOpenApi(text)) { await handlePotentialOpenApiPaste(text); } + state = state.copyWith(isGenerating: false, currentStreamingResponse: ''); return; } else { systemPrompt = promptBuilder.buildSystemPrompt( @@ -431,6 +436,8 @@ class ChatViewmodel extends StateNotifier { // quick check final trimmed = text.trim(); if (!trimmed.startsWith('curl ')) return; + // Show loading while parsing and generating insights + state = state.copyWith(isGenerating: true, currentStreamingResponse: ''); try { debugPrint('[cURL] Original: $trimmed'); final curl = CurlImportService.tryParseCurl(trimmed); @@ -528,6 +535,11 @@ class ChatViewmodel extends StateNotifier { final safe = e.toString().replaceAll('"', "'"); _appendSystem('{"explnation":"Parsing failed: $safe","actions":[]}', ChatMessageType.importCurl); + } finally { + state = state.copyWith( + isGenerating: false, + currentStreamingResponse: '', + ); } } @@ -581,6 +593,8 @@ class ChatViewmodel extends StateNotifier { Future handlePotentialOpenApiPaste(String text) async { final trimmed = text.trim(); if (!_looksLikeOpenApi(trimmed)) return; + // Show loading while parsing and generating insights + state = state.copyWith(isGenerating: true, currentStreamingResponse: ''); try { debugPrint('[OpenAPI] Original length: ${trimmed.length}'); final spec = OpenApiImportService.tryParseSpec(trimmed); @@ -647,6 +661,11 @@ class ChatViewmodel extends StateNotifier { final safe = e.toString().replaceAll('"', "'"); _appendSystem('{"explnation":"Parsing failed: $safe","actions":[]}', ChatMessageType.importOpenApi); + } finally { + state = state.copyWith( + isGenerating: false, + currentStreamingResponse: '', + ); } }