Update Dashbot

This commit is contained in:
siddu015
2025-03-23 23:09:27 +05:30
parent 6d1ceeee3c
commit 7c5a841fb7
7 changed files with 11 additions and 37 deletions

View File

@@ -2,11 +2,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:apidash/dashbot/widgets/dashbot_widget.dart'; import 'package:apidash/dashbot/widgets/dashbot_widget.dart';
// Provider to manage DashBot visibility state
final dashBotVisibilityProvider = StateProvider<bool>((ref) => false); final dashBotVisibilityProvider = StateProvider<bool>((ref) => false);
final dashBotMinimizedProvider = StateProvider<bool>((ref) => false); final dashBotMinimizedProvider = StateProvider<bool>((ref) => false);
// Function to show DashBot in a bottom sheet (old style)
void showDashBotBottomSheet(BuildContext context) { void showDashBotBottomSheet(BuildContext context) {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
@@ -18,13 +16,11 @@ void showDashBotBottomSheet(BuildContext context) {
); );
} }
// Function to toggle DashBot overlay (new style)
void toggleDashBotOverlay(WidgetRef ref) { void toggleDashBotOverlay(WidgetRef ref) {
ref.read(dashBotVisibilityProvider.notifier).state = true; ref.read(dashBotVisibilityProvider.notifier).state = true;
ref.read(dashBotMinimizedProvider.notifier).state = false; ref.read(dashBotMinimizedProvider.notifier).state = false;
} }
// DashBot Overlay Widget
class DashBotOverlay extends ConsumerWidget { class DashBotOverlay extends ConsumerWidget {
const DashBotOverlay({super.key}); const DashBotOverlay({super.key});
@@ -36,7 +32,7 @@ class DashBotOverlay extends ConsumerWidget {
elevation: 8, elevation: 8,
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
child: SizedBox( child: SizedBox(
width: 400, // Fixed width for the DashBot width: 400,
height: isMinimized ? 120 : 450, height: isMinimized ? 120 : 450,
child: const DashBotWidget(), child: const DashBotWidget(),
), ),
@@ -44,7 +40,6 @@ class DashBotOverlay extends ConsumerWidget {
} }
} }
// FloatingActionButton for DashBot
class DashBotFAB extends ConsumerWidget { class DashBotFAB extends ConsumerWidget {
final bool useOverlay; final bool useOverlay;

View File

@@ -1,5 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import '../services/dashbot_service.dart'; import 'package:apidash/dashbot/services/dashbot_service.dart';
import 'package:apidash/models/request_model.dart'; import 'package:apidash/models/request_model.dart';
class DocumentationFeature { class DocumentationFeature {

View File

@@ -7,7 +7,6 @@ class GeneralQueryFeature {
GeneralQueryFeature(this._client); GeneralQueryFeature(this._client);
Future<String> generateResponse(String prompt, {RequestModel? requestModel, dynamic responseModel}) async { Future<String> generateResponse(String prompt, {RequestModel? requestModel, dynamic responseModel}) async {
// Create a more focused prompt that incorporates request/response context if available
String enhancedPrompt = prompt; String enhancedPrompt = prompt;
if (requestModel != null && responseModel != null) { if (requestModel != null && responseModel != null) {

View File

@@ -22,20 +22,15 @@ class TestGeneratorFeature {
.toUpperCase() ?? .toUpperCase() ??
"GET"; "GET";
final endpoint = requestModel.httpRequestModel?.url ?? "Unknown Endpoint"; final endpoint = requestModel.httpRequestModel?.url ?? "Unknown Endpoint";
final headers = requestModel.httpRequestModel?.enabledHeadersMap ?? {};
final parameters = requestModel.httpRequestModel?.enabledParamsMap ?? {};
final body = requestModel.httpRequestModel?.body;
final rawResponse = responseModel.body; final rawResponse = responseModel.body;
final responseBody = final responseBody =
rawResponse is String ? rawResponse : jsonEncode(rawResponse); rawResponse is String ? rawResponse : jsonEncode(rawResponse);
final statusCode = responseModel.statusCode ?? 0; final statusCode = responseModel.statusCode ?? 0;
// Extract base URL and endpoint path
Uri uri = Uri.parse(endpoint); Uri uri = Uri.parse(endpoint);
final baseUrl = "${uri.scheme}://${uri.host}"; final baseUrl = "${uri.scheme}://${uri.host}";
final path = uri.path; final path = uri.path;
// Analyze parameter types and values
final parameterAnalysis = _analyzeParameters(uri.queryParameters); final parameterAnalysis = _analyzeParameters(uri.queryParameters);
final prompt = """ final prompt = """
@@ -67,11 +62,7 @@ For each test case:
Focus on creating realistic test values based on the API context (e.g., for a country flag API, use real country codes, invalid codes, etc.) Focus on creating realistic test values based on the API context (e.g., for a country flag API, use real country codes, invalid codes, etc.)
"""; """;
// Generate the test cases
final testCases = await _service.generateResponse(prompt); final testCases = await _service.generateResponse(prompt);
// Return only a button trigger message with the test cases hidden
// This will be detected in DashBotWidget to show only a button instead of the full text
return "TEST_CASES_HIDDEN\n$testCases"; return "TEST_CASES_HIDDEN\n$testCases";
} }
@@ -83,7 +74,6 @@ Focus on creating realistic test values based on the API context (e.g., for a co
Map<String, String> analysis = {}; Map<String, String> analysis = {};
parameters.forEach((key, value) { parameters.forEach((key, value) {
// Try to determine parameter type and format
if (RegExp(r'^[A-Z]{3}$').hasMatch(value)) { if (RegExp(r'^[A-Z]{3}$').hasMatch(value)) {
analysis[key] = "Appears to be a 3-letter country code (ISO 3166-1 alpha-3)"; analysis[key] = "Appears to be a 3-letter country code (ISO 3166-1 alpha-3)";
} else if (RegExp(r'^[A-Z]{2}$').hasMatch(value)) { } else if (RegExp(r'^[A-Z]{2}$').hasMatch(value)) {

View File

@@ -2,7 +2,7 @@ import 'package:apidash/dashbot/features/debug.dart';
import 'package:apidash/dashbot/features/documentation.dart'; import 'package:apidash/dashbot/features/documentation.dart';
import 'package:ollama_dart/ollama_dart.dart'; import 'package:ollama_dart/ollama_dart.dart';
import 'package:apidash/dashbot/features/explain.dart'; import 'package:apidash/dashbot/features/explain.dart';
import 'package:apidash/dashbot/features/test_generator.dart'; // New import import 'package:apidash/dashbot/features/test_generator.dart';
import 'package:apidash/models/request_model.dart'; import 'package:apidash/models/request_model.dart';
import 'package:apidash/dashbot/features/general_query.dart'; import 'package:apidash/dashbot/features/general_query.dart';
@@ -11,7 +11,7 @@ class DashBotService {
late final ExplainFeature _explainFeature; late final ExplainFeature _explainFeature;
late final DebugFeature _debugFeature; late final DebugFeature _debugFeature;
late final DocumentationFeature _documentationFeature; late final DocumentationFeature _documentationFeature;
late final TestGeneratorFeature _testGeneratorFeature; // New feature late final TestGeneratorFeature _testGeneratorFeature;
final GeneralQueryFeature _generalQueryFeature; final GeneralQueryFeature _generalQueryFeature;
DashBotService() DashBotService()
@@ -20,7 +20,7 @@ class DashBotService {
_explainFeature = ExplainFeature(this); _explainFeature = ExplainFeature(this);
_debugFeature = DebugFeature(this); _debugFeature = DebugFeature(this);
_documentationFeature = DocumentationFeature(this); _documentationFeature = DocumentationFeature(this);
_testGeneratorFeature = TestGeneratorFeature(this); // Initialize new feature _testGeneratorFeature = TestGeneratorFeature(this);
} }
Future<String> generateResponse(String prompt) async { Future<String> generateResponse(String prompt) async {
@@ -38,7 +38,7 @@ class DashBotService {
} else if (input == "Document API") { } else if (input == "Document API") {
return _documentationFeature.generateApiDocumentation( return _documentationFeature.generateApiDocumentation(
requestModel: requestModel, responseModel: responseModel); requestModel: requestModel, responseModel: responseModel);
} else if (input == "Test API") { // New condition } else if (input == "Test API") {
return _testGeneratorFeature.generateApiTests( return _testGeneratorFeature.generateApiTests(
requestModel: requestModel, responseModel: responseModel); requestModel: requestModel, responseModel: responseModel);
} }

View File

@@ -7,7 +7,9 @@ import 'test_runner_widget.dart';
import 'chat_bubble.dart'; import 'chat_bubble.dart';
class DashBotWidget extends ConsumerStatefulWidget { class DashBotWidget extends ConsumerStatefulWidget {
const DashBotWidget({super.key}); const DashBotWidget({
super.key,
});
@override @override
ConsumerState<DashBotWidget> createState() => _DashBotWidgetState(); ConsumerState<DashBotWidget> createState() => _DashBotWidgetState();
@@ -33,7 +35,6 @@ class _DashBotWidgetState extends ConsumerState<DashBotWidget> {
Future<void> _sendMessage(String message) async { Future<void> _sendMessage(String message) async {
if (message.trim().isEmpty) return; if (message.trim().isEmpty) return;
final dashBotService = ref.read(dashBotServiceProvider); final dashBotService = ref.read(dashBotServiceProvider);
final requestModel = ref.read(selectedRequestModelProvider); final requestModel = ref.read(selectedRequestModelProvider);
final responseModel = requestModel?.httpResponseModel; final responseModel = requestModel?.httpResponseModel;
@@ -48,13 +49,8 @@ class _DashBotWidgetState extends ConsumerState<DashBotWidget> {
try { try {
final response = await dashBotService.handleRequest( final response = await dashBotService.handleRequest(
message, requestModel, responseModel); message, requestModel, responseModel);
// Check if this is a test case response with hidden content
if (response.startsWith("TEST_CASES_HIDDEN\n")) { if (response.startsWith("TEST_CASES_HIDDEN\n")) {
// Extract the test cases but don't show them in the message
final testCases = response.replaceFirst("TEST_CASES_HIDDEN\n", ""); final testCases = response.replaceFirst("TEST_CASES_HIDDEN\n", "");
// Add a message with a marker that will trigger the button display
ref.read(chatMessagesProvider.notifier).addMessage({ ref.read(chatMessagesProvider.notifier).addMessage({
'role': 'bot', 'role': 'bot',
'message': "Test cases generated successfully. Click the button below to run them.", 'message': "Test cases generated successfully. Click the button below to run them.",
@@ -62,7 +58,6 @@ class _DashBotWidgetState extends ConsumerState<DashBotWidget> {
'showTestButton': true, 'showTestButton': true,
}); });
} else { } else {
// Normal message handling
ref.read(chatMessagesProvider.notifier).addMessage({ ref.read(chatMessagesProvider.notifier).addMessage({
'role': 'bot', 'role': 'bot',
'message': response, 'message': response,
@@ -135,7 +130,6 @@ class _DashBotWidgetState extends ConsumerState<DashBotWidget> {
Widget _buildHeader(BuildContext context) { Widget _buildHeader(BuildContext context) {
final isMinimized = ref.watch(dashBotMinimizedProvider); final isMinimized = ref.watch(dashBotMinimizedProvider);
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(16, 16, 16, 0), padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
child: Row( child: Row(
@@ -147,7 +141,6 @@ class _DashBotWidgetState extends ConsumerState<DashBotWidget> {
), ),
Row( Row(
children: [ children: [
// Minimize/Maximize button with proper alignment
IconButton( IconButton(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
@@ -160,7 +153,6 @@ class _DashBotWidgetState extends ConsumerState<DashBotWidget> {
ref.read(dashBotMinimizedProvider.notifier).state = !isMinimized; ref.read(dashBotMinimizedProvider.notifier).state = !isMinimized;
}, },
), ),
// Close button
IconButton( IconButton(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
@@ -170,7 +162,6 @@ class _DashBotWidgetState extends ConsumerState<DashBotWidget> {
ref.read(dashBotVisibilityProvider.notifier).state = false; ref.read(dashBotVisibilityProvider.notifier).state = false;
}, },
), ),
// Clear chat button
IconButton( IconButton(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
@@ -302,7 +293,6 @@ class _DashBotWidgetState extends ConsumerState<DashBotWidget> {
Widget _buildInputArea(BuildContext context) { Widget _buildInputArea(BuildContext context) {
final isMinimized = ref.watch(dashBotMinimizedProvider); final isMinimized = ref.watch(dashBotMinimizedProvider);
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),

View File

@@ -1,8 +1,8 @@
import 'dart:convert';
import 'package:apidash_core/apidash_core.dart' as http;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'content_renderer.dart'; import 'content_renderer.dart';
class TestRunnerWidget extends ConsumerStatefulWidget { class TestRunnerWidget extends ConsumerStatefulWidget {