From 8caa03c677d276d16ba1f053d548b556fe24d1a5 Mon Sep 17 00:00:00 2001 From: Mrudul111 Date: Tue, 25 Mar 2025 09:17:44 +0530 Subject: [PATCH 1/6] llm model change --- lib/consts.dart | 5 ++ lib/dashbot/providers/dashbot_providers.dart | 19 ++++++- lib/dashbot/services/dashbot_service.dart | 54 +++++++++++++++++--- lib/dashbot/widgets/dashbot_widget.dart | 23 +++++++++ lib/main.dart | 3 ++ lib/screens/dashboard.dart | 22 ++++---- pubspec.lock | 32 ++++++++++++ pubspec.yaml | 2 + 8 files changed, 140 insertions(+), 20 deletions(-) diff --git a/lib/consts.dart b/lib/consts.dart index 595aa69e7..1ff036f79 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -145,6 +145,11 @@ enum ImportFormat { const ImportFormat(this.label); final String label; } +enum LLMProvider { + ollama, + gemini, + openai +} const String kGlobalEnvironmentId = "global"; diff --git a/lib/dashbot/providers/dashbot_providers.dart b/lib/dashbot/providers/dashbot_providers.dart index 2015d6a82..f26635400 100644 --- a/lib/dashbot/providers/dashbot_providers.dart +++ b/lib/dashbot/providers/dashbot_providers.dart @@ -1,17 +1,23 @@ import 'dart:convert'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import '../../consts.dart'; import '../services/dashbot_service.dart'; final chatMessagesProvider = - StateNotifierProvider>>( - (ref) => ChatMessagesNotifier(), +StateNotifierProvider>>( + (ref) => ChatMessagesNotifier(), ); final dashBotServiceProvider = Provider((ref) { return DashBotService(); }); +final selectedLLMProvider = +StateNotifierProvider( + (ref) => SelectedLLMNotifier(), +); + class ChatMessagesNotifier extends StateNotifier>> { ChatMessagesNotifier() : super([]) { _loadMessages(); @@ -42,3 +48,12 @@ class ChatMessagesNotifier extends StateNotifier>> { _saveMessages(); } } + +/// Manages the selected LLM (only in memory) +class SelectedLLMNotifier extends StateNotifier { + SelectedLLMNotifier() : super(LLMProvider.ollama); // Default LLM + + void setSelectedLLM(LLMProvider model) { + state = model; + } +} diff --git a/lib/dashbot/services/dashbot_service.dart b/lib/dashbot/services/dashbot_service.dart index 8eb0087c8..474a5e18b 100644 --- a/lib/dashbot/services/dashbot_service.dart +++ b/lib/dashbot/services/dashbot_service.dart @@ -1,24 +1,64 @@ import 'package:apidash/dashbot/features/debug.dart'; import 'package:ollama_dart/ollama_dart.dart'; +import 'package:openai_dart/openai_dart.dart'; +import 'package:flutter_gemini/flutter_gemini.dart'; +import '../../consts.dart'; import '../features/explain.dart'; import 'package:apidash/models/request_model.dart'; + class DashBotService { - final OllamaClient _client; + late final OllamaClient _ollamaClient; + late final OpenAIClient _openAiClient; late final ExplainFeature _explainFeature; late final DebugFeature _debugFeature; + LLMProvider _selectedModel = LLMProvider.ollama; + DashBotService() - : _client = OllamaClient(baseUrl: 'http://127.0.0.1:11434/api') { + : _ollamaClient = OllamaClient(baseUrl: 'http://127.0.0.1:11434/api'), + //TODO: Add API key to .env file + _openAiClient = OpenAIClient(apiKey: "your_openai_api_key") { _explainFeature = ExplainFeature(this); _debugFeature = DebugFeature(this); } + void setModel(LLMProvider model) { + _selectedModel = model; + } + Future generateResponse(String prompt) async { - final response = await _client.generateCompletion( - request: GenerateCompletionRequest(model: 'llama3.2:3b', prompt: prompt), - ); - return response.response.toString(); + try { + switch (_selectedModel) { + case LLMProvider.gemini: + final response = await Gemini.instance.chat([ + Content(parts: [Part.text(prompt)], role: 'user') + ]); + return response?.output ?? "Error: No response from Gemini."; + + case LLMProvider.ollama: + final response = await _ollamaClient.generateCompletion( + request: GenerateCompletionRequest(model: 'llama3.2:3b', prompt: prompt), + ); + return response.response.toString(); + + case LLMProvider.openai: + final response = await _openAiClient.createChatCompletion( + request: CreateChatCompletionRequest( + model: ChatCompletionModel.modelId('gpt-4o'), + messages: [ + ChatCompletionMessage.user( + content: ChatCompletionUserMessageContent.string(prompt), + ), + ], + temperature: 0, + ), + ); + return response.choices?.first.message?.content ?? "Error: No response from OpenAI."; + } + } catch (e) { + return "Error: ${e.toString()}"; + } } Future handleRequest( @@ -33,4 +73,4 @@ class DashBotService { return generateResponse(input); } -} +} \ No newline at end of file diff --git a/lib/dashbot/widgets/dashbot_widget.dart b/lib/dashbot/widgets/dashbot_widget.dart index 200d4c5fa..d4e0ce3e3 100644 --- a/lib/dashbot/widgets/dashbot_widget.dart +++ b/lib/dashbot/widgets/dashbot_widget.dart @@ -1,8 +1,10 @@ // lib/dashbot/widgets/dashbot_widget.dart +import 'package:apidash_core/apidash_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:apidash/dashbot/providers/dashbot_providers.dart'; import 'package:apidash/providers/providers.dart'; +import '../../consts.dart'; import 'chat_bubble.dart'; class DashBotWidget extends ConsumerStatefulWidget { @@ -94,6 +96,8 @@ class _DashBotWidgetState extends ConsumerState { children: [ _buildHeader(context), const SizedBox(height: 12), + _buildModelSelector(), + const SizedBox(height: 12), _buildQuickActions(showDebugButton), const SizedBox(height: 12), Expanded(child: _buildChatArea(messages)), @@ -104,6 +108,25 @@ class _DashBotWidgetState extends ConsumerState { ), ); } + Widget _buildModelSelector() { + final selectedLLM = ref.watch(selectedLLMProvider); + + return DropdownButton( + value: selectedLLM, + items: LLMProvider.values.map((provider) { + return DropdownMenuItem( + value: provider, + child: Text(provider.name.capitalize()), + ); + }).toList(), + onChanged: (LLMProvider? newProvider) { + if (newProvider != null) { + ref.read(selectedLLMProvider.notifier).state = newProvider; + ref.read(dashBotServiceProvider).setModel(newProvider); + } + }, + ); + } Widget _buildHeader(BuildContext context) { return Row( diff --git a/lib/main.dart b/lib/main.dart index 8b5fab32a..765ed4651 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'package:apidash_design_system/apidash_design_system.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_gemini/flutter_gemini.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'models/models.dart'; import 'providers/providers.dart'; @@ -9,6 +10,8 @@ import 'app.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); + //TODO: Add API key to .env file + Gemini.init(apiKey: "apiKey"); var settingsModel = await getSettingsFromSharedPrefs(); final initStatus = await initApp( kIsDesktop, diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index 428ffaebc..cc9a62670 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -126,17 +126,17 @@ class Dashboard extends ConsumerWidget { ), ), // TODO: Release DashBot - // floatingActionButton: FloatingActionButton( - // onPressed: () => showModalBottomSheet( - // context: context, - // isScrollControlled: true, - // builder: (context) => const Padding( - // padding: EdgeInsets.all(16.0), - // child: DashBotWidget(), - // ), - // ), - // child: const Icon(Icons.help_outline), - // ), + floatingActionButton: FloatingActionButton( + onPressed: () => showModalBottomSheet( + context: context, + isScrollControlled: true, + builder: (context) => const Padding( + padding: EdgeInsets.all(16.0), + child: DashBotWidget(), + ), + ), + child: const Icon(Icons.help_outline), + ), ); } } diff --git a/pubspec.lock b/pubspec.lock index b16f69dd4..1da08269e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -350,6 +350,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.0" + dio: + dependency: transitive + description: + name: dio + sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" + url: "https://pub.dev" + source: hosted + version: "5.8.0+1" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.dev" + source: hosted + version: "2.1.1" equatable: dependency: transitive description: @@ -520,6 +536,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_gemini: + dependency: "direct main" + description: + name: flutter_gemini + sha256: b7264b1d19acc4b1a5628a0e26c0976aa1fb948f0d3243bc3510ff51e09476b7 + url: "https://pub.dev" + source: hosted + version: "3.0.0" flutter_highlighter: dependency: "direct main" description: @@ -1097,6 +1121,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.2+1" + openai_dart: + dependency: "direct main" + description: + name: openai_dart + sha256: "1cc5ed0915fa7572b943de01cfa7a3e5cfe1e6a7f4d0d9a9374d046518e84575" + url: "https://pub.dev" + source: hosted + version: "0.4.5" package_config: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index af67db989..3e3444b39 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -69,6 +69,8 @@ dependencies: git: url: https://github.com/google/flutter-desktop-embedding.git path: plugins/window_size + openai_dart: ^0.4.5 + flutter_gemini: ^3.0.0 dependency_overrides: extended_text_field: ^16.0.0 From 87b4d03b0beb17934bd924c276ca4ff15820ee80 Mon Sep 17 00:00:00 2001 From: Mrudul Killedar <90367225+Mrudul111@users.noreply.github.com> Date: Fri, 28 Mar 2025 23:53:26 +0530 Subject: [PATCH 2/6] Create Application_Mrudul Killedar_DashBot gsoc proposal initial draft --- .../gsoc/Application_Mrudul Killedar_DashBot | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot diff --git a/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot b/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot new file mode 100644 index 000000000..f4a6d11e2 --- /dev/null +++ b/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot @@ -0,0 +1,110 @@ +# GSOC Proposal for DashBot + +## About Me +**Full Name:** Mrudul Killedar +**Email:** mrudulkilledar111@gmail.com +**Phone:** +91 7489685683 +**Discord Handle:** Mrudul +**GitHub Profile:** https://github.com/Mrudul111 +**LinkedIn:** www.linkedin.com/in/mrudul-killedar-5b0121245 +**Time Zone:** GMT + 5:30 +**Resume:** https://drive.google.com/file/d/1ICvI5h8FP5cTtMIvQcu918Adc5JP1DQb/view?usp=share_link + +## University Information +**University Name:** Vellore Institute of Technology +**Program:** B.Tech in Computer Science Engineering +**Year:** 2025 +**Expected Graduation Date:** July 2025 + +## Motivation & Past Experience +**1. Have you worked on or contributed to a FOSS project before?** +Yes, I have contributed to FOSS project ie APIDash: +- Solves Beautify JSON and Highlight JSOn - https://github.com/foss42/apidash/pull/595 +- Share button functionality - https://github.com/foss42/apidash/pull/571#event-16324056931 +- Homebrew Installation Guide - https://github.com/foss42/apidash/pull/566#event-16282262849 +- Multiple-Model in DashBot - https://github.com/foss42/apidash/pull/704 + +**2. What is your one project/achievement that you are most proud of? Why?** +I am most proud of 2 projects particularly one is Parking24 which is an app that was made to solve parking problems of UAE market and i was assigned this project in my internship at Wisho (Now called Hyve AI Labs). +I am proud of the project because it is adding real world value and solving a very real problem. Also i have been working on a Machine learning model that is to predict cybersickness using SNN and currently we are achieving accuracy of 87.234% which is better than existing model that has accuracy of 76.11% and we achieved this because of our better approach for data cleaning. + +**3. What kind of problems or challenges motivate you the most to solve them?** +I am most motivated by solving complex problems that challenge me to think in new ways and push my boundaries. I enjoy tackling problems that I have never encountered before, as they provide an opportunity to learn, explore innovative solutions, and develop a deeper understanding of different technologies. The thrill of breaking down a difficult problem, analyzing it from different angles, and coming up with an effective solution is what drives me the most. + +**4. Will you be working on GSoC full-time?** +Yes, I will be working full-time on my GSoC project. + +**5. Do you mind regularly syncing up with the project mentors?** +Not at all! I am happy to have regular sync-ups with my mentors to ensure smooth progress and alignment with project goals. + +**6. What interests you the most about API Dash?** +API Dash is an innovative tool that simplifies API testing and monitoring. I personally felt other apps are very bloated and performace is really clunky on the other hand API Dash is really smooth, looks aesthetically pleasing and use of AI just seperates them from rest of the API Testing Platform. I have personally shifted to API Dash for my backend testing. I would love to contribute to API Dash because i feel this is a project that is adding such a great value to developer community. + +**7. Can you mention some areas where the project can be improved?** +Some areas where API Dash can be improved include: +- **UI for DashBot:** The UI currently is very basic and lacks a professional approach. +- **Responses:** The response that is generated by clicking the buttons is on-point but the bot is not conversational enough. + + +## Project Proposal Information +### **Proposal Title:** DashBot + +### **Abstract** +DashBot is an AI-powered assistant designed to supercharge developer productivity within API Dash by automating repetitive tasks, improving API debugging, and providing intelligent recommendations. By leveraging advanced large language models (LLMs), DashBot enables developers to interact with APIs using natural language, making API testing, debugging, documentation, and integration significantly more efficient and intuitive. + +### **Detailed Description** +DashBot is designed to be an AI-powered assistant for API Dash that helps developers automate tedious tasks, follow best practices, and obtain contextual suggestions via natural-language input. This project extends its capabilities by adding the following advanced features: + +#### **1. AI-Powered Code Error Detection & Auto-Fix** +- Detect syntax and logical errors in API requests and integration code. +- Provide human-readable explanations and suggest one-click fixes. +- Ensure best practices in authentication, rate limiting, and error handling. +- **Flutter Packages:** [`dart_code_metrics`](https://pub.dev/packages/dart_code_metrics), [`lsp_dart`](https://pub.dev/packages/lsp_dart), [`openai_dart`](https://pub.dev/packages/openai_dart) + +#### **2. Multi-Model Support & Fine-Tuning** +- Enable users to switch between different LLMs (GPT, Llama, Claude, Gemini, etc.). +- Provide on-device LLM support for private inference. +- Allow user-defined prompt fine-tuning for personalized suggestions. +- **Flutter Packages:** [`ollama_flutter`](https://pub.dev/packages/ollama_flutter), [`tflite_flutter`](https://pub.dev/packages/tflite_flutter), [`http`](https://pub.dev/packages/http) + +#### **3. Multi-Language API Code Generation & AI-Powered Auto Refactoring** +- Extend API code generation to Kotlin, Swift, Go, and Rust. +- Auto-refactor generated code for better maintainability and efficiency. +- Provide real-time code quality analysis and performance suggestions. +- **Flutter Packages:** [`dart_style`](https://pub.dev/packages/dart_style), [`flutter_highlight`](https://pub.dev/packages/flutter_highlight), [`language_server_protocol`](https://pub.dev/packages/language_server_protocol) + +#### **4. AI-Driven API Contract Testing & Schema Validation** +- Auto-detect API schema inconsistencies with OpenAPI, GraphQL, JSON Schema. +- Flag breaking changes and provide regression testing for API updates. +- Generate mock API contracts for frontend and backend teams. +- **Flutter Packages:** [`json_schema`](https://pub.dev/packages/json_schema), [`dio`](https://pub.dev/packages/dio), [`openapi_parser`](https://pub.dev/packages/openapi_parser) + +#### **5. AI-Powered API Performance & Load Testing** +- Predict API performance bottlenecks and optimize response times. +- Simulate real-world API traffic patterns for scalability testing. +- Suggest optimal rate limits and caching strategies based on usage trends. +- **Flutter Packages:** [`flutter_jmeter`](https://pub.dev/packages/flutter_jmeter), [`isolate`](https://pub.dev/packages/isolate), [`statsfl`](https://pub.dev/packages/statsfl) + +#### **6. AI-Assisted API Integration Testing Across Platforms** +- Auto-generate end-to-end API tests for **Flutter, React, Next.js, etc.** +- Ensure consistent API behavior across web and mobile applications. +- Test authentication workflows, session handling, and cross-platform API interactions. +- Provide real-time debugging assistance inside development environments. +- **Flutter Packages:** [`integration_test`](https://pub.dev/packages/integration_test), [`mockito`](https://pub.dev/packages/mockito), [`flutter_test`](https://api.flutter.dev/flutter/flutter_test/flutter_test-library.html) + +### **Weekly Timeline** + +| **Week** | **Task** | +|----------|---------| +| Week 1 | Implement AI-powered test case generation for API requests | +| Week 2 | Develop initial integration with API Dash and set up AI-based testing modules | +| Week 3 | Conduct testing, refine AI model responses, and improve performance | +| Week 4 | Implement intelligent API documentation generation with auto-explanations | +| Week 5 | Enhance UI/UX for generated documentation, including markdown formatting and syntax highlighting | +| Week 6 | Gather user feedback, refine documentation AI, and introduce auto-refactoring for better maintainability | +| Week 7 | Implement AI-driven response visualization, including charts and statistical insights | +| Week 8 | Integrate debugging assistance, including error detection and auto-fixes for API requests | +| Week 9 | Improve UI elements, streamline workflows, and optimize model performance for faster processing | +| Week 10 | Conduct final testing, polish features, and document best practices for AI-based API automation | + +--- From 5bccdedb81be2fe9ffba0b21d731465b5ef0dce8 Mon Sep 17 00:00:00 2001 From: Mrudul Killedar <90367225+Mrudul111@users.noreply.github.com> Date: Fri, 28 Mar 2025 23:54:52 +0530 Subject: [PATCH 3/6] Rename Application_Mrudul Killedar_DashBot to Application_Mrudul Killedar_DashBot.md making into md file --- ...ul Killedar_DashBot => Application_Mrudul Killedar_DashBot.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/proposals/2025/gsoc/{Application_Mrudul Killedar_DashBot => Application_Mrudul Killedar_DashBot.md} (100%) diff --git a/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot b/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot.md similarity index 100% rename from doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot rename to doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot.md From 08487c43154b019ff0db31ae5e0be4f0608a7224 Mon Sep 17 00:00:00 2001 From: Mrudul Killedar <90367225+Mrudul111@users.noreply.github.com> Date: Fri, 28 Mar 2025 23:55:50 +0530 Subject: [PATCH 4/6] Update Application_Mrudul Killedar_DashBot.md --- doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot.md b/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot.md index f4a6d11e2..f02a8c619 100644 --- a/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot.md +++ b/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot.md @@ -19,7 +19,7 @@ ## Motivation & Past Experience **1. Have you worked on or contributed to a FOSS project before?** Yes, I have contributed to FOSS project ie APIDash: -- Solves Beautify JSON and Highlight JSOn - https://github.com/foss42/apidash/pull/595 +- Solves Beautify JSON and Highlight JSON - https://github.com/foss42/apidash/pull/595 - Share button functionality - https://github.com/foss42/apidash/pull/571#event-16324056931 - Homebrew Installation Guide - https://github.com/foss42/apidash/pull/566#event-16282262849 - Multiple-Model in DashBot - https://github.com/foss42/apidash/pull/704 From 157969f7462c718cd9a6664fc6dac187a525e90f Mon Sep 17 00:00:00 2001 From: Mrudul111 Date: Fri, 28 Mar 2025 23:59:49 +0530 Subject: [PATCH 5/6] model selection added --- lib/dashbot/providers/dashbot_providers.dart | 68 +++++++++++++---- lib/dashbot/providers/llm_provider.dart | 22 ++++++ lib/dashbot/services/dashbot_service.dart | 79 ++++++++++++++------ lib/dashbot/widgets/dashbot_widget.dart | 72 +++++++++++++----- lib/main.dart | 2 - lib/screens/dashboard.dart | 22 +++--- 6 files changed, 196 insertions(+), 69 deletions(-) create mode 100644 lib/dashbot/providers/llm_provider.dart diff --git a/lib/dashbot/providers/dashbot_providers.dart b/lib/dashbot/providers/dashbot_providers.dart index f26635400..fe5654338 100644 --- a/lib/dashbot/providers/dashbot_providers.dart +++ b/lib/dashbot/providers/dashbot_providers.dart @@ -4,19 +4,15 @@ import 'package:shared_preferences/shared_preferences.dart'; import '../../consts.dart'; import '../services/dashbot_service.dart'; +// Chat Messages Provider final chatMessagesProvider = StateNotifierProvider>>( - (ref) => ChatMessagesNotifier(), -); + (ref) => ChatMessagesNotifier()); -final dashBotServiceProvider = Provider((ref) { - return DashBotService(); -}); final selectedLLMProvider = StateNotifierProvider( - (ref) => SelectedLLMNotifier(), -); + (ref) => SelectedLLMNotifier()); class ChatMessagesNotifier extends StateNotifier>> { ChatMessagesNotifier() : super([]) { @@ -26,10 +22,14 @@ class ChatMessagesNotifier extends StateNotifier>> { static const _storageKey = 'chatMessages'; Future _loadMessages() async { - final prefs = await SharedPreferences.getInstance(); - final messages = prefs.getString(_storageKey); - if (messages != null) { - state = List>.from(json.decode(messages)); + try { + final prefs = await SharedPreferences.getInstance(); + final messages = prefs.getString(_storageKey); + if (messages != null) { + state = List>.from(json.decode(messages)); + } + } catch (e) { + print("Error loading messages: $e"); } } @@ -49,11 +49,51 @@ class ChatMessagesNotifier extends StateNotifier>> { } } -/// Manages the selected LLM (only in memory) class SelectedLLMNotifier extends StateNotifier { - SelectedLLMNotifier() : super(LLMProvider.ollama); // Default LLM + SelectedLLMNotifier() : super(LLMProvider.ollama) { + _loadSelectedLLM(); + } + + static const _storageKey = 'selectedLLM'; + + Future _loadSelectedLLM() async { + final prefs = await SharedPreferences.getInstance(); + final savedValue = prefs.getString(_storageKey); + if (savedValue != null) { + state = LLMProvider.values.firstWhere( + (e) => e.toString() == savedValue, + orElse: () => LLMProvider.ollama, + ); + } + } - void setSelectedLLM(LLMProvider model) { + Future setSelectedLLM(LLMProvider provider) async { + state = provider; + final prefs = await SharedPreferences.getInstance(); + await prefs.setString(_storageKey, provider.toString()); + } +} +final selectedLLMModelProvider = StateNotifierProvider( + (ref) => SelectedLLMModelNotifier(), +); + +class SelectedLLMModelNotifier extends StateNotifier { + SelectedLLMModelNotifier() : super("mistral") { + _loadSelectedLLMModel(); + } + + static const _storageKey = 'selectedLLMModel'; + + Future _loadSelectedLLMModel() async { + final prefs = await SharedPreferences.getInstance(); + state = prefs.getString(_storageKey) ?? "mistral"; + } + + Future setSelectedLLMModel(String model) async { state = model; + final prefs = await SharedPreferences.getInstance(); + await prefs.setString(_storageKey, model); } } + + diff --git a/lib/dashbot/providers/llm_provider.dart b/lib/dashbot/providers/llm_provider.dart new file mode 100644 index 000000000..5a80dc006 --- /dev/null +++ b/lib/dashbot/providers/llm_provider.dart @@ -0,0 +1,22 @@ +class LLMConfig { + final String model; + String? apiUrl; + String? apiKey; + double? temperature; + + LLMConfig({ + required this.model, + this.apiUrl, + this.apiKey, + this.temperature, + }); + + LLMConfig copyWith({String? apiUrl, String? apiKey, String? model, double? temperature}) { + return LLMConfig( + model: model ?? this.model, + apiUrl: apiUrl ?? this.apiUrl, + apiKey: apiKey ?? this.apiKey, + temperature: temperature ?? this.temperature, + ); + } +} diff --git a/lib/dashbot/services/dashbot_service.dart b/lib/dashbot/services/dashbot_service.dart index 474a5e18b..be1966ccf 100644 --- a/lib/dashbot/services/dashbot_service.dart +++ b/lib/dashbot/services/dashbot_service.dart @@ -5,62 +5,93 @@ import 'package:flutter_gemini/flutter_gemini.dart'; import '../../consts.dart'; import '../features/explain.dart'; import 'package:apidash/models/request_model.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../providers/dashbot_providers.dart'; +import '../providers/llm_provider.dart'; + +final llmConfigProvider = StateNotifierProvider>((ref) { + return LLMConfigNotifier(); +}); + +class LLMConfigNotifier extends StateNotifier> { + LLMConfigNotifier() + : super({ + LLMProvider.ollama: LLMConfig(apiUrl: "http://127.0.0.1:11434/api", model: "mistral"), + LLMProvider.gemini: LLMConfig(apiKey: "gemini_api_key", model: "gemini-1.5"), + LLMProvider.openai: LLMConfig(apiKey: "openAI_api_key", model: "gpt-4-turbo"), + }); + + void updateConfig(LLMProvider provider, LLMConfig newConfig) { + state = {...state, provider: newConfig}; + } +} + +final dashBotServiceProvider = Provider((ref) => DashBotService(ref, LLMProvider.ollama)); class DashBotService { - late final OllamaClient _ollamaClient; - late final OpenAIClient _openAiClient; - late final ExplainFeature _explainFeature; - late final DebugFeature _debugFeature; + late OllamaClient _ollamaClient; + late OpenAIClient _openAiClient; + late Gemini _geminiClient; + late ExplainFeature _explainFeature; + late DebugFeature _debugFeature; + final Ref _ref; - LLMProvider _selectedModel = LLMProvider.ollama; - DashBotService() - : _ollamaClient = OllamaClient(baseUrl: 'http://127.0.0.1:11434/api'), - //TODO: Add API key to .env file - _openAiClient = OpenAIClient(apiKey: "your_openai_api_key") { + DashBotService(this._ref, LLMProvider selectedModel) { + _initializeClients(); _explainFeature = ExplainFeature(this); _debugFeature = DebugFeature(this); } - void setModel(LLMProvider model) { - _selectedModel = model; + void _initializeClients() { + final config = _ref.read(llmConfigProvider); + + _ollamaClient = OllamaClient(baseUrl: config[LLMProvider.ollama]!.apiUrl,); + _openAiClient = OpenAIClient(apiKey: config[LLMProvider.openai]!.apiKey ?? "",); + _geminiClient = Gemini.init(apiKey: config[LLMProvider.gemini]!.apiKey ?? "", ); } Future generateResponse(String prompt) async { try { - switch (_selectedModel) { + final selectedProvider = _ref.read(selectedLLMProvider); + final config = _ref.read(llmConfigProvider)[selectedProvider]!; + + switch (selectedProvider) { case LLMProvider.gemini: - final response = await Gemini.instance.chat([ - Content(parts: [Part.text(prompt)], role: 'user') + final response = await Gemini.instance.chat( + modelName: config.model, + [ + Content(parts: [Part.text(prompt)], role: 'user',), ]); return response?.output ?? "Error: No response from Gemini."; - case LLMProvider.ollama: - final response = await _ollamaClient.generateCompletion( - request: GenerateCompletionRequest(model: 'llama3.2:3b', prompt: prompt), - ); - return response.response.toString(); - case LLMProvider.openai: final response = await _openAiClient.createChatCompletion( request: CreateChatCompletionRequest( - model: ChatCompletionModel.modelId('gpt-4o'), + model: ChatCompletionModel.modelId(config.model), messages: [ ChatCompletionMessage.user( content: ChatCompletionUserMessageContent.string(prompt), ), ], - temperature: 0, + temperature: config.temperature ?? 0.7, ), ); - return response.choices?.first.message?.content ?? "Error: No response from OpenAI."; + return response.choices.first.message.content ?? "Error: No response from OpenAI."; + + case LLMProvider.ollama: + final response = await _ollamaClient.generateCompletion( + request: GenerateCompletionRequest(model: config.model, prompt: prompt), + ); + return response.response.toString(); } } catch (e) { return "Error: ${e.toString()}"; } } + Future handleRequest( String input, RequestModel? requestModel, dynamic responseModel) async { if (input == "Explain API") { @@ -73,4 +104,4 @@ class DashBotService { return generateResponse(input); } -} \ No newline at end of file +} diff --git a/lib/dashbot/widgets/dashbot_widget.dart b/lib/dashbot/widgets/dashbot_widget.dart index d4e0ce3e3..24b4a7ff5 100644 --- a/lib/dashbot/widgets/dashbot_widget.dart +++ b/lib/dashbot/widgets/dashbot_widget.dart @@ -1,10 +1,10 @@ -// lib/dashbot/widgets/dashbot_widget.dart import 'package:apidash_core/apidash_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:apidash/dashbot/providers/dashbot_providers.dart'; import 'package:apidash/providers/providers.dart'; import '../../consts.dart'; +import '../services/dashbot_service.dart'; import 'chat_bubble.dart'; class DashBotWidget extends ConsumerStatefulWidget { @@ -109,25 +109,61 @@ class _DashBotWidgetState extends ConsumerState { ); } Widget _buildModelSelector() { - final selectedLLM = ref.watch(selectedLLMProvider); - - return DropdownButton( - value: selectedLLM, - items: LLMProvider.values.map((provider) { - return DropdownMenuItem( - value: provider, - child: Text(provider.name.capitalize()), - ); - }).toList(), - onChanged: (LLMProvider? newProvider) { - if (newProvider != null) { - ref.read(selectedLLMProvider.notifier).state = newProvider; - ref.read(dashBotServiceProvider).setModel(newProvider); - } - }, + return Row( + children: [ + DropdownButton( + value: ref.watch(selectedLLMProvider), + onChanged: (LLMProvider? newProvider) { + if (newProvider != null) { + ref.read(selectedLLMProvider.notifier).setSelectedLLM(newProvider); + } + }, + items: LLMProvider.values.map((provider) { + return DropdownMenuItem( + value: provider, + child: Text(provider.toString().split('.').last), + ); + }).toList(), + ), + SizedBox(width: 20,), + Consumer(builder: (context, ref, _) { + final selectedProvider = ref.watch(selectedLLMProvider); + final config = ref.watch(llmConfigProvider)[selectedProvider]!; + + List models = []; + switch (selectedProvider) { + case LLMProvider.gemini: + models = ["gemini-1.0", "gemini-1.5", "gemini-pro", "gemini-ultra"]; + break; + case LLMProvider.openai: + models = ["gpt-3.5-turbo", "gpt-4-turbo", "gpt-4"]; + break; + case LLMProvider.ollama: + models = ["mistral", "llama2", "codellama", "gemma"]; + break; + } + + return DropdownButton( + value: config.model, + onChanged: (String? newModel) { + if (newModel != null) { + ref.read(llmConfigProvider.notifier).updateConfig( + selectedProvider, + config.copyWith(model: newModel), + ); + } + }, + items: models.map((model) { + return DropdownMenuItem( + value: model, + child: Text(model), + ); + }).toList(), + ); + }), + ], ); } - Widget _buildHeader(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, diff --git a/lib/main.dart b/lib/main.dart index 765ed4651..2df21ffd3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,8 +10,6 @@ import 'app.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); - //TODO: Add API key to .env file - Gemini.init(apiKey: "apiKey"); var settingsModel = await getSettingsFromSharedPrefs(); final initStatus = await initApp( kIsDesktop, diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index cc9a62670..428ffaebc 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -126,17 +126,17 @@ class Dashboard extends ConsumerWidget { ), ), // TODO: Release DashBot - floatingActionButton: FloatingActionButton( - onPressed: () => showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (context) => const Padding( - padding: EdgeInsets.all(16.0), - child: DashBotWidget(), - ), - ), - child: const Icon(Icons.help_outline), - ), + // floatingActionButton: FloatingActionButton( + // onPressed: () => showModalBottomSheet( + // context: context, + // isScrollControlled: true, + // builder: (context) => const Padding( + // padding: EdgeInsets.all(16.0), + // child: DashBotWidget(), + // ), + // ), + // child: const Icon(Icons.help_outline), + // ), ); } } From 906843f490a1994c5976f2ef2c99a5fa168069e7 Mon Sep 17 00:00:00 2001 From: Mrudul111 Date: Sat, 29 Mar 2025 00:03:29 +0530 Subject: [PATCH 6/6] removed proposal from dashbot branch --- .../Application_Mrudul Killedar_DashBot.md | 110 ------------------ 1 file changed, 110 deletions(-) delete mode 100644 doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot.md diff --git a/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot.md b/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot.md deleted file mode 100644 index f02a8c619..000000000 --- a/doc/proposals/2025/gsoc/Application_Mrudul Killedar_DashBot.md +++ /dev/null @@ -1,110 +0,0 @@ -# GSOC Proposal for DashBot - -## About Me -**Full Name:** Mrudul Killedar -**Email:** mrudulkilledar111@gmail.com -**Phone:** +91 7489685683 -**Discord Handle:** Mrudul -**GitHub Profile:** https://github.com/Mrudul111 -**LinkedIn:** www.linkedin.com/in/mrudul-killedar-5b0121245 -**Time Zone:** GMT + 5:30 -**Resume:** https://drive.google.com/file/d/1ICvI5h8FP5cTtMIvQcu918Adc5JP1DQb/view?usp=share_link - -## University Information -**University Name:** Vellore Institute of Technology -**Program:** B.Tech in Computer Science Engineering -**Year:** 2025 -**Expected Graduation Date:** July 2025 - -## Motivation & Past Experience -**1. Have you worked on or contributed to a FOSS project before?** -Yes, I have contributed to FOSS project ie APIDash: -- Solves Beautify JSON and Highlight JSON - https://github.com/foss42/apidash/pull/595 -- Share button functionality - https://github.com/foss42/apidash/pull/571#event-16324056931 -- Homebrew Installation Guide - https://github.com/foss42/apidash/pull/566#event-16282262849 -- Multiple-Model in DashBot - https://github.com/foss42/apidash/pull/704 - -**2. What is your one project/achievement that you are most proud of? Why?** -I am most proud of 2 projects particularly one is Parking24 which is an app that was made to solve parking problems of UAE market and i was assigned this project in my internship at Wisho (Now called Hyve AI Labs). -I am proud of the project because it is adding real world value and solving a very real problem. Also i have been working on a Machine learning model that is to predict cybersickness using SNN and currently we are achieving accuracy of 87.234% which is better than existing model that has accuracy of 76.11% and we achieved this because of our better approach for data cleaning. - -**3. What kind of problems or challenges motivate you the most to solve them?** -I am most motivated by solving complex problems that challenge me to think in new ways and push my boundaries. I enjoy tackling problems that I have never encountered before, as they provide an opportunity to learn, explore innovative solutions, and develop a deeper understanding of different technologies. The thrill of breaking down a difficult problem, analyzing it from different angles, and coming up with an effective solution is what drives me the most. - -**4. Will you be working on GSoC full-time?** -Yes, I will be working full-time on my GSoC project. - -**5. Do you mind regularly syncing up with the project mentors?** -Not at all! I am happy to have regular sync-ups with my mentors to ensure smooth progress and alignment with project goals. - -**6. What interests you the most about API Dash?** -API Dash is an innovative tool that simplifies API testing and monitoring. I personally felt other apps are very bloated and performace is really clunky on the other hand API Dash is really smooth, looks aesthetically pleasing and use of AI just seperates them from rest of the API Testing Platform. I have personally shifted to API Dash for my backend testing. I would love to contribute to API Dash because i feel this is a project that is adding such a great value to developer community. - -**7. Can you mention some areas where the project can be improved?** -Some areas where API Dash can be improved include: -- **UI for DashBot:** The UI currently is very basic and lacks a professional approach. -- **Responses:** The response that is generated by clicking the buttons is on-point but the bot is not conversational enough. - - -## Project Proposal Information -### **Proposal Title:** DashBot - -### **Abstract** -DashBot is an AI-powered assistant designed to supercharge developer productivity within API Dash by automating repetitive tasks, improving API debugging, and providing intelligent recommendations. By leveraging advanced large language models (LLMs), DashBot enables developers to interact with APIs using natural language, making API testing, debugging, documentation, and integration significantly more efficient and intuitive. - -### **Detailed Description** -DashBot is designed to be an AI-powered assistant for API Dash that helps developers automate tedious tasks, follow best practices, and obtain contextual suggestions via natural-language input. This project extends its capabilities by adding the following advanced features: - -#### **1. AI-Powered Code Error Detection & Auto-Fix** -- Detect syntax and logical errors in API requests and integration code. -- Provide human-readable explanations and suggest one-click fixes. -- Ensure best practices in authentication, rate limiting, and error handling. -- **Flutter Packages:** [`dart_code_metrics`](https://pub.dev/packages/dart_code_metrics), [`lsp_dart`](https://pub.dev/packages/lsp_dart), [`openai_dart`](https://pub.dev/packages/openai_dart) - -#### **2. Multi-Model Support & Fine-Tuning** -- Enable users to switch between different LLMs (GPT, Llama, Claude, Gemini, etc.). -- Provide on-device LLM support for private inference. -- Allow user-defined prompt fine-tuning for personalized suggestions. -- **Flutter Packages:** [`ollama_flutter`](https://pub.dev/packages/ollama_flutter), [`tflite_flutter`](https://pub.dev/packages/tflite_flutter), [`http`](https://pub.dev/packages/http) - -#### **3. Multi-Language API Code Generation & AI-Powered Auto Refactoring** -- Extend API code generation to Kotlin, Swift, Go, and Rust. -- Auto-refactor generated code for better maintainability and efficiency. -- Provide real-time code quality analysis and performance suggestions. -- **Flutter Packages:** [`dart_style`](https://pub.dev/packages/dart_style), [`flutter_highlight`](https://pub.dev/packages/flutter_highlight), [`language_server_protocol`](https://pub.dev/packages/language_server_protocol) - -#### **4. AI-Driven API Contract Testing & Schema Validation** -- Auto-detect API schema inconsistencies with OpenAPI, GraphQL, JSON Schema. -- Flag breaking changes and provide regression testing for API updates. -- Generate mock API contracts for frontend and backend teams. -- **Flutter Packages:** [`json_schema`](https://pub.dev/packages/json_schema), [`dio`](https://pub.dev/packages/dio), [`openapi_parser`](https://pub.dev/packages/openapi_parser) - -#### **5. AI-Powered API Performance & Load Testing** -- Predict API performance bottlenecks and optimize response times. -- Simulate real-world API traffic patterns for scalability testing. -- Suggest optimal rate limits and caching strategies based on usage trends. -- **Flutter Packages:** [`flutter_jmeter`](https://pub.dev/packages/flutter_jmeter), [`isolate`](https://pub.dev/packages/isolate), [`statsfl`](https://pub.dev/packages/statsfl) - -#### **6. AI-Assisted API Integration Testing Across Platforms** -- Auto-generate end-to-end API tests for **Flutter, React, Next.js, etc.** -- Ensure consistent API behavior across web and mobile applications. -- Test authentication workflows, session handling, and cross-platform API interactions. -- Provide real-time debugging assistance inside development environments. -- **Flutter Packages:** [`integration_test`](https://pub.dev/packages/integration_test), [`mockito`](https://pub.dev/packages/mockito), [`flutter_test`](https://api.flutter.dev/flutter/flutter_test/flutter_test-library.html) - -### **Weekly Timeline** - -| **Week** | **Task** | -|----------|---------| -| Week 1 | Implement AI-powered test case generation for API requests | -| Week 2 | Develop initial integration with API Dash and set up AI-based testing modules | -| Week 3 | Conduct testing, refine AI model responses, and improve performance | -| Week 4 | Implement intelligent API documentation generation with auto-explanations | -| Week 5 | Enhance UI/UX for generated documentation, including markdown formatting and syntax highlighting | -| Week 6 | Gather user feedback, refine documentation AI, and introduce auto-refactoring for better maintainability | -| Week 7 | Implement AI-driven response visualization, including charts and statistical insights | -| Week 8 | Integrate debugging assistance, including error detection and auto-fixes for API requests | -| Week 9 | Improve UI elements, streamline workflows, and optimize model performance for faster processing | -| Week 10 | Conduct final testing, polish features, and document best practices for AI-based API automation | - ----