Dashbot History saving and an option to clear

This commit is contained in:
siddu015
2025-02-26 23:28:58 +05:30
parent 6ab86fbf90
commit 7b271a8ecd
5 changed files with 102 additions and 26 deletions

View File

@ -0,0 +1,38 @@
import 'dart:convert';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
final chatMessagesProvider = StateNotifierProvider<ChatMessagesNotifier, List<Map<String, dynamic>>>(
(ref) => ChatMessagesNotifier(),
);
class ChatMessagesNotifier extends StateNotifier<List<Map<String, dynamic>>> {
ChatMessagesNotifier() : super([]) {
_loadMessages();
}
static const _storageKey = 'chatMessages';
Future<void> _loadMessages() async {
final prefs = await SharedPreferences.getInstance();
final messages = prefs.getString(_storageKey);
if (messages != null) {
state = List<Map<String, dynamic>>.from(json.decode(messages));
}
}
Future<void> _saveMessages() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_storageKey, json.encode(state));
}
void addMessage(Map<String, dynamic> message) {
state = [...state, message];
_saveMessages();
}
void clearMessages() {
state = [];
_saveMessages();
}
}

View File

@ -4,3 +4,5 @@ export 'history_providers.dart';
export 'settings_providers.dart';
export 'ui_providers.dart';
export 'ollama_providers.dart';
export 'dashbot_messages.dart';

View File

@ -54,7 +54,6 @@ class ResponseDetails extends ConsumerWidget {
.watch(selectedRequestModelProvider.select((value) => value?.message));
final responseModel = ref.watch(selectedRequestModelProvider
.select((value) => value?.httpResponseModel));
return Column(
children: [
ResponsePaneHeader(

View File

@ -17,10 +17,15 @@ class OllamaService {
return response.response.toString();
}
// Explain latest API request & response
// Explain responses & identify any discrepancy
Future<String> explainLatestApi({required dynamic requestModel, required dynamic responseModel}) async {
if (requestModel == null || responseModel == null) {
return "No recent API requests found";
return "No recent API requests found.";
}
// Validate critical fields
if (requestModel.httpRequestModel?.url == null) {
return "Error: Invalid API request (missing endpoint).";
}
// Extract request details
@ -28,43 +33,44 @@ class OllamaService {
.toString()
.split('.')
.last
.toUpperCase()
?? "GET";
final endpoint = requestModel.httpRequestModel?.url ?? "Unknown endpoint";
.toUpperCase() ?? "GET";
final endpoint = requestModel.httpRequestModel!.url!;
final headers = requestModel.httpRequestModel?.enabledHeadersMap ?? {};
final parameters = requestModel.httpRequestModel?.enabledParamsMap ?? {};
final body = requestModel.httpRequestModel?.body;
// Process response
final rawResponse = responseModel.body;
final responseBody = rawResponse is String;
final responseBody = rawResponse is String ? rawResponse : jsonEncode(rawResponse);
final statusCode = responseModel.statusCode ?? 0;
final prompt = '''
Analyze this API interaction following these examples:
Analyze this API interaction and **identify discrepancies**:
Current API Request:
- Endpoint: $endpoint
- Method: $method
**API Request:**
- Endpoint: `$endpoint`
- Method: `$method`
- Headers: ${headers.isNotEmpty ? jsonEncode(headers) : "None"}
- Parameters: ${parameters.isNotEmpty ? jsonEncode(parameters) : "None"}
- Body: ${body ?? "None"}
Current Response:
**API Response:**
- Status Code: $statusCode
- Response Body: ${jsonEncode(responseBody)}
- Body:
\`\`\`json
$responseBody
\`\`\`
Required Analysis Format:
1. Start with overall status assessment
2. List validation/security issues
3. Highlight request/response mismatches
4. Suggest concrete improvements
5. Use plain text formatting with clear section headers
**Instructions:**
1. Start with a **summary** of the API interaction.
2. List **validation issues** (e.g., missing headers, invalid parameters).
3. Highlight **request/response mismatches** (e.g., unexpected data types, missing fields).
4. Suggest **concrete improvements** (e.g., fix parameters, add error handling).
Response Structure:
API Request: [request details]
Response: [response details]
Analysis: [structured analysis]''';
**Format:**
- Use Markdown with headings (`##`, `###`).
- Include bullet points for clarity.
''';
return generateResponse(prompt);
}

View File

@ -12,9 +12,10 @@ class ChatbotWidget extends ConsumerStatefulWidget {
class _ChatbotWidgetState extends ConsumerState<ChatbotWidget> {
final TextEditingController _controller = TextEditingController();
final List<Map<String, dynamic>> _messages = [];
bool _isLoading = false;
List<Map<String, dynamic>> get _messages => ref.watch(chatMessagesProvider);
Future<void> _handleCodeGeneration() async {
final language = await showDialog<String>(
context: context,
@ -56,11 +57,14 @@ class _ChatbotWidgetState extends ConsumerState<ChatbotWidget> {
final responseModel = requestModel?.httpResponseModel;
setState(() {
_messages.add({'role': 'user', 'message': message});
_controller.clear();
_isLoading = true;
});
ref.read(chatMessagesProvider.notifier).addMessage({
'role': 'user',
'message': message
});
try {
String response;
@ -123,6 +127,18 @@ class _ChatbotWidgetState extends ConsumerState<ChatbotWidget> {
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('DashBot', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
IconButton(
icon: const Icon(Icons.delete_sweep),
tooltip: 'Clear Chat History',
onPressed: () => ref.read(chatMessagesProvider.notifier).clearMessages(),
),
],
),
const SizedBox(height: 8),
Wrap(
spacing: 8,
runSpacing: 8,
@ -224,6 +240,21 @@ class ChatBubble extends StatelessWidget {
child: MarkdownBody(
data: message,
selectable: true,
styleSheet: MarkdownStyleSheet(
h2: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.onSurface,
),
h3: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.onSurface,
),
listBullet: TextStyle(
color: Theme.of(context).colorScheme.onSurface,
),
),
),
),
);